MrForExample 10 months ago
parent
commit
b4ffaee5dc
  1. 40
      README.md
  2. 83
      __init__.py
  3. 5
      alter-list.json
  4. 2
      components/.gitignore
  5. 166
      custom-node-list.json
  6. 374
      extension-node-map.json
  7. 326
      js/comfyui-manager.js
  8. 13
      js/common.js
  9. 801
      js/components-manager.js
  10. 60
      js/snapshot.js
  11. 444
      misc/Impact.pack
  12. 46
      node_db/dev/custom-node-list.json
  13. 25
      node_db/dev/extension-node-map.json
  14. 352
      node_db/new/custom-node-list.json
  15. 374
      node_db/new/extension-node-map.json
  16. 30
      node_db/tutorial/custom-node-list.json
  17. 9
      prestartup_script.py

40
README.md

@ -63,6 +63,7 @@ This repository provides Colab notebooks that allow you to install and use Comfy
* Support for automatically installing dependencies of custom nodes upon restarting Colab notebooks.
## Changes
* **2.2.3** Support Components System
* **0.29** Add `Update all` feature
* **0.25** support db channel
* You can directly modify the db channel settings in the `config.ini` file.
@ -208,6 +209,41 @@ NODE_CLASS_MAPPINGS.update({
* **All scripts are executed from the root path of the corresponding custom node.**
## Component Sharing
* **Copy & Paste**
* [Demo Page](https://ltdrdata.github.io/component-demo/)
* When pasting a component from the clipboard, it supports text in the following JSON format. (text/plain)
```
{
"kind": "ComfyUI Components",
"timestamp": <current timestamp>,
"components":
{
<component name>: <component nodedata>
}
}
```
* `<current timestamp>` Ensure that the timestamp is always unique.
* "components" should have the same structure as the content of the file stored in ComfyUI-Manager/components.
* `<component name>`: The name should be in the format `<prefix>::<node name>`.
* `<compnent nodeata>`: In the nodedata of the group node.
* `<version>`: Only two formats are allowed: `major.minor.patch` or `major.minor`. (e.g. `1.0`, `2.2.1`)
* `<datetime>`: Saved time
* `<packname>`: If the packname is not empty, the category becomes packname/workflow, and it is saved in the <packname>.pack file in ComfyUI-Manager/components.
* `<category>`: If there is neither a category nor a packname, it is saved in the components category.
```
"version":"1.0",
"datetime": 1705390656516,
"packname": "mypack",
"category": "util/pipe",
```
* **Drag & Drop**
* Dragging and dropping a `.pack` or `.json` file will add the corresponding components.
* Example pack: [Impact.pack](misc/Impact.pack)
* Dragging and dropping or pasting a single component will add a node. However, when adding multiple components, nodes will not be added.
## Support of missing nodes installation
![missing-menu](misc/missing-menu.png)
@ -240,11 +276,11 @@ NODE_CLASS_MAPPINGS.update({
- [x] System displaying information about failed custom nodes import.
- [x] Guide for missing nodes in ComfyUI vanilla nodes.
- [x] Collision checking system for nodes with the same ID across extensions.
- [x] Template sharing system. (-> Component system based on Group Nodes)
- [x] 3rd party API system.
- [ ] Auto migration for custom nodes with changed structures.
- [ ] Version control feature for nodes.
- [ ] List of currently used custom nodes.
- [ ] Template sharing system.
- [ ] 3rd party API system.
- [ ] Download support multiple model download.
- [ ] Model download via url.
- [ ] List sorting.

83
__init__.py

@ -28,12 +28,11 @@ except:
print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.")
version = [1, 26]
version = [2, 2, 3]
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
print(f"### Loading: ComfyUI-Manager ({version_str})")
required_comfyui_revision = 1793
comfy_ui_hash = "-"
cache_lock = threading.Lock()
@ -118,6 +117,7 @@ local_db_alter = os.path.join(comfyui_manager_path, "alter-list.json")
local_db_custom_node_list = os.path.join(comfyui_manager_path, "custom-node-list.json")
local_db_extension_node_mappings = os.path.join(comfyui_manager_path, "extension-node-map.json")
git_script_path = os.path.join(os.path.dirname(__file__), "git_helper.py")
components_path = os.path.join(comfyui_manager_path, 'components')
startup_script_path = os.path.join(comfyui_manager_path, "startup-scripts")
config_path = os.path.join(os.path.dirname(__file__), "config.ini")
@ -171,6 +171,7 @@ def write_config():
'share_option': get_config()['share_option'],
'bypass_ssl': get_config()['bypass_ssl'],
'default_ui': get_config()['default_ui'],
'component_policy': get_config()['component_policy'],
}
with open(config_path, 'w') as configfile:
config.write(configfile)
@ -190,6 +191,7 @@ def read_config():
'share_option': default_conf['share_option'] if 'share_option' in default_conf else 'all',
'bypass_ssl': default_conf['bypass_ssl'] if 'bypass_ssl' in default_conf else False,
'default_ui': default_conf['default_ui'] if 'default_ui' in default_conf else 'none',
'component_policy': default_conf['component_policy'] if 'component_policy' in default_conf else 'workflow',
}
except Exception:
@ -200,7 +202,8 @@ def read_config():
'channel_url': 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main',
'share_option': 'all',
'bypass_ssl': False,
'default_ui': 'none'
'default_ui': 'none',
'component_policy': 'workflow'
}
@ -248,6 +251,10 @@ def set_default_ui_mode(mode):
get_config()['default_ui'] = mode
def set_component_policy(mode):
get_config()['component_policy'] = mode
def try_install_script(url, repo_path, install_cmd):
int_comfyui_revision = 0
@ -1766,6 +1773,18 @@ async def default_ui_mode(request):
return web.Response(status=200)
@server.PromptServer.instance.routes.get("/manager/component/policy")
async def component_policy(request):
if "value" in request.rel_url.query:
set_component_policy(request.rel_url.query['value'])
write_config()
else:
return web.Response(text=get_config()['component_policy'], status=200)
return web.Response(status=200)
@server.PromptServer.instance.routes.get("/manager/channel_url_list")
async def channel_url_list(request):
channels = get_channel_dict()
@ -1838,6 +1857,64 @@ def restart(self):
return os.execv(sys.executable, [sys.executable] + sys.argv)
def sanitize_filename(input_string):
# 알파벳, 숫자, 및 밑줄 이외의 문자를 밑줄로 대체
result_string = re.sub(r'[^a-zA-Z0-9_]', '_', input_string)
return result_string
@server.PromptServer.instance.routes.post("/manager/component/save")
async def save_component(request):
try:
data = await request.json()
name = data['name']
workflow = data['workflow']
if not os.path.exists(components_path):
os.mkdir(components_path)
if 'packname' in workflow and workflow['packname'] != '':
sanitized_name = sanitize_filename(workflow['packname'])+'.pack'
else:
sanitized_name = sanitize_filename(name)+'.json'
filepath = os.path.join(components_path, sanitized_name)
components = {}
if os.path.exists(filepath):
with open(filepath) as f:
components = json.load(f)
components[name] = workflow
with open(filepath, 'w') as f:
json.dump(components, f, indent=4, sort_keys=True)
return web.Response(text=filepath, status=200)
except:
return web.Response(status=400)
@server.PromptServer.instance.routes.post("/manager/component/loads")
async def load_components(request):
try:
json_files = [f for f in os.listdir(components_path) if f.endswith('.json')]
pack_files = [f for f in os.listdir(components_path) if f.endswith('.pack')]
components = {}
for json_file in json_files + pack_files:
file_path = os.path.join(components_path, json_file)
with open(file_path, 'r') as file:
try:
# When there is a conflict between the .pack and the .json, the pack takes precedence and overrides.
components.update(json.load(file))
except json.JSONDecodeError as e:
print(f"[ComfyUI-Manager] Error decoding component file in file {json_file}: {e}")
return web.json_response(components)
except Exception as e:
print(f"[ComfyUI-Manager] failed to load components\n{e}")
return web.Response(status=400)
@server.PromptServer.instance.routes.get("/manager/share_option")
async def share_option(request):
if "value" in request.rel_url.query:

5
alter-list.json

@ -194,6 +194,11 @@
"id":"https://github.com/shiimizu/ComfyUI-TiledDiffusion",
"tags":"multidiffusion",
"description": "This extension provides custom nodes for [a/Mixture of Diffusers](https://github.com/albarji/mixture-of-diffusers) and [a/MultiDiffusion](https://github.com/omerbt/MultiDiffusion)"
},
{
"id":"https://github.com/abyz22/image_control",
"tags":"BMAB",
"description": "This extension provides some alternative functionalities of the [a/sd-webui-bmab](https://github.com/portu-sim/sd-webui-bmab) extension."
}
]
}

2
components/.gitignore vendored

@ -0,0 +1,2 @@
*.json
*.pack

166
custom-node-list.json

@ -2878,7 +2878,7 @@
"https://github.com/GTSuya-Studio/ComfyUI-Gtsuya-Nodes"
],
"install_type": "git-clone",
"description": "ComfyUI-GTSuya-Nodes is a ComyUI extension designed to add several wildcards supports into ComfyUI. Wildcards allow you to use __name__ syntax in your prompt to get a random line from a file named name.txt in a wildcards directory."
"description": "ComfyUI-GTSuya-Nodes is a ComfyUI extension designed to add several wildcards supports into ComfyUI. Wildcards allow you to use __name__ syntax in your prompt to get a random line from a file named name.txt in a wildcards directory."
},
{
"author": "oyvindg",
@ -3539,7 +3539,7 @@
"https://github.com/vienteck/ComfyUI-Chat-GPT-Integration"
],
"install_type": "git-clone",
"description": "This extension is a reimagined version based on the [a/ComfyUI-QualityOfLifeSuit_Omar92](https://github.com/omar92/ComfyUI-QualityOfLifeSuit_Omar92) extension, and it supports integration with ChatGPT through the new OpenAI API.\nNOTE: See detailed installation instructions on the [a/repository](https://github.com/vienteck/ComfyUI-Chat-GPT-Integration)."
},
{
@ -4064,6 +4064,16 @@
"install_type": "git-clone",
"description": "Nodes: Download the weights of MotionCtrl [a/motionctrl.pth](https://huggingface.co/TencentARC/MotionCtrl/blob/main/motionctrl.pth) and put it to ComfyUI/models/checkpoints"
},
{
"author": "chaojie",
"title": "ComfyUI-MotionCtrl-SVD",
"reference": "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD",
"files": [
"https://github.com/chaojie/ComfyUI-MotionCtrl-SVD"
],
"install_type": "git-clone",
"description": "Nodes: Download the weights of MotionCtrl-SVD [a/motionctrl_svd.ckpt](https://huggingface.co/TencentARC/MotionCtrl/blob/main/motionctrl_svd.ckpt) and put it to ComfyUI/models/checkpoints"
},
{
"author": "chaojie",
"title": "ComfyUI-DragNUWA",
@ -4074,6 +4084,26 @@
"install_type": "git-clone",
"description": "Nodes: Download the weights of DragNUWA [a/drag_nuwa_svd.pth](https://drive.google.com/file/d/1Z4JOley0SJCb35kFF4PCc6N6P1ftfX4i/view) and put it to ComfyUI/models/checkpoints/drag_nuwa_svd.pth"
},
{
"author": "chaojie",
"title": "ComfyUI-Moore-AnimateAnyone",
"reference": "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone",
"files": [
"https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone"
],
"install_type": "git-clone",
"description": "Nodes: Run python tools/download_weights.py first to download weights automatically"
},
{
"author": "chaojie",
"title": "ComfyUI-I2VGEN-XL",
"reference": "https://github.com/chaojie/ComfyUI-I2VGEN-XL",
"files": [
"https://github.com/chaojie/ComfyUI-I2VGEN-XL"
],
"install_type": "git-clone",
"description": "This is an implementation of [a/i2vgen-xl](https://github.com/ali-vilab/i2vgen-xl)"
},
{
"author": "alexopus",
"title": "ComfyUI Image Saver",
@ -4104,6 +4134,16 @@
"install_type": "git-clone",
"description": "An extensive node suite that enables ComfyUI to process 3D inputs (Mesh & UV Texture, etc) using cutting edge algorithms (3DGS, NeRF, etc.)"
},
{
"author": "MrForExample",
"title": "ComfyUI-AnimateAnyone-Evolved",
"reference": "https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved",
"files": [
"https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved"
],
"install_type": "git-clone",
"description": "Improved [a/AnimateAnyone](https://github.com/HumanAIGC/AnimateAnyone) implementation that allows you to use the opse image sequence and reference image to generate stylized video."
},
{
"author": "Hangover3832",
"title": "ComfyUI-Hangover-Nodes",
@ -4234,6 +4274,128 @@
"install_type": "git-clone",
"description": "Instead of LoraLoader or HypernetworkLoader, it receives a prompt and loads and applies LoRA or HN based on the specifications within the prompt. The main purpose of this custom node is to allow changes without reconnecting the LoraLoader node when the prompt is randomly altered, etc."
},
{
"author": "Taremin",
"title": "ComfyUI String Tools",
"reference": "https://github.com/Taremin/comfyui-string-tools",
"files": [
"https://github.com/Taremin/comfyui-string-tools"
],
"install_type": "git-clone",
"description": " This extension provides the StringToolsConcat node, which concatenates multiple texts, and the StringToolsRandomChoice node, which selects one randomly from multiple texts."
},
{
"author": "foxtrot-roger",
"title": "RF Nodes",
"reference": "https://github.com/foxtrot-roger/comfyui-rf-nodes",
"files": [
"https://github.com/foxtrot-roger/comfyui-rf-nodes"
],
"install_type": "git-clone",
"description": "A bunch of nodes that can be useful to manipulate primitive types (numbers, text, ...) Also some helpers to generate text and timestamps."
},
{
"author": "abyz22",
"title": "image_control",
"reference": "https://github.com/abyz22/image_control",
"files": [
"https://github.com/abyz22/image_control"
],
"install_type": "git-clone",
"description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor"
},
{
"author": "HAL41",
"title": "ComfyUI aichemy nodes",
"reference": "https://github.com/HAL41/ComfyUI-aichemy-nodes",
"files": [
"https://github.com/HAL41/ComfyUI-aichemy-nodes"
],
"install_type": "git-clone",
"description": "Simple node to handle scaling of YOLOv8 segmentation masks"
},
{
"author": "nkchocoai",
"title": "ComfyUI-SizeFromPresets",
"reference": "https://github.com/nkchocoai/ComfyUI-SizeFromPresets",
"files": [
"https://github.com/nkchocoai/ComfyUI-SizeFromPresets"
],
"install_type": "git-clone",
"description": "Add a node that outputs width and height of the size selected from the preset (.csv)."
},
{
"author": "JaredTherriault",
"title": "ComfyUI-JNodes",
"reference": "https://github.com/JaredTherriault/ComfyUI-JNodes",
"files": [
"https://github.com/JaredTherriault/ComfyUI-JNodes"
],
"install_type": "git-clone",
"description": "python and web UX improvements for ComfyUI.\n[w/'DynamicPrompts.js' and 'EditAttention.js' from the core, along with 'ImageFeed.js' and 'favicon.js' from the custom scripts of pythongosssss, are not compatible. Therefore, manual deletion of these files is required to use this web extension.]"
},
{
"author": "prozacgod",
"title": "ComfyUI Multi-Workspace",
"reference": "https://github.com/prozacgod/comfyui-pzc-multiworkspace",
"files": [
"https://github.com/prozacgod/comfyui-pzc-multiworkspace"
],
"install_type": "git-clone",
"description": "A simple, quick, and dirty implementation of multiple workspaces within ComfyUI."
},
{
"author": "Siberpone",
"title": "Lazy Pony Prompter",
"reference": "https://github.com/Siberpone/lazy-pony-prompter",
"files": [
"https://github.com/Siberpone/lazy-pony-prompter"
],
"install_type": "git-clone",
"description": "A pony prompt helper extension for AUTOMATIC1111's Stable Diffusion Web UI and ComfyUI that utilizes the full power of your favorite booru query syntax. Currently supports [a/Derpibooru](https://derpibooru/org) and [a/E621](https://e621.net/)."
},
{
"author": "kijai",
"title": "ComfyUI-DDColor",
"reference": "https://github.com/kijai/ComfyUI-DDColor",
"files": [
"https://github.com/kijai/ComfyUI-DDColor"
],
"install_type": "git-clone",
"description": "Node to use [a/DDColor](https://github.com/piddnad/DDColor) in ComfyUI."
},
{
"author": "chflame163",
"title": "ComfyUI Layer Style",
"reference": "https://github.com/chflame163/ComfyUI_LayerStyle",
"files": [
"https://github.com/chflame163/ComfyUI_LayerStyle"
],
"install_type": "git-clone",
"description": "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress."
},
{
"author": "dave-palt",
"title": "comfyui_DSP_imagehelpers",
"reference": "https://github.com/dave-palt/comfyui_DSP_imagehelpers",
"files": [
"https://github.com/dave-palt/comfyui_DSP_imagehelpers"
],
"install_type": "git-clone",
"description": "Nodes: DSP Image Concat"
},
{
"author": "Inzaniak",
"title": "Ranbooru for ComfyUI",
"reference": "https://github.com/Inzaniak/comfyui-ranbooru",
"files": [
"https://github.com/Inzaniak/comfyui-ranbooru"
],
"install_type": "git-clone",
"description": "Ranbooru is an extension for the comfyUI. The purpose of this extension is to add a node that gets a random set of tags from boorus pictures. This is mostly being used to help me test my checkpoints on a large variety of"
},
{

374
extension-node-map.json

@ -116,8 +116,17 @@
[
"ApplyMaskToImage-badger",
"CropImageByMask-badger",
"ExpandImageWithColor-badger",
"FindThickLinesFromCanny-badger",
"FloatToInt-badger",
"FloatToString-badger",
"FrameToVideo-badger",
"GarbageCollect-badger",
"GetColorFromBorder-badger",
"GetDirName-badger",
"GetUUID-badger",
"IdentifyBorderColorToMask-badger",
"IdentifyColorToMask-badger",
"ImageNormalization-badger",
"ImageOverlap-badger",
"ImageScaleToSide-badger",
@ -125,7 +134,9 @@
"SegmentToMaskByPoint-badger",
"StringToFizz-badger",
"TextListToString-badger",
"VideoCut-badger",
"TrimTransparentEdges-badger",
"VideoCutFromDir-badger",
"VideoToFrame-badger",
"deleteDir-badger",
"findCenterOfMask-badger",
"getImageSide-badger",
@ -261,7 +272,9 @@
[
"ComfyUIDeployExternalImage",
"ComfyUIDeployExternalImageAlpha",
"ComfyUIDeployExternalLora",
"ComfyUIDeployExternalNumber",
"ComfyUIDeployExternalNumberInt",
"ComfyUIDeployExternalText"
],
{
@ -837,6 +850,14 @@
"title_aux": "ReActor Node for ComfyUI"
}
],
"https://github.com/HAL41/ComfyUI-aichemy-nodes": [
[
"aichemyYOLOv8Segmentation"
],
{
"title_aux": "ComfyUI aichemy nodes"
}
],
"https://github.com/Hangover3832/ComfyUI-Hangover-Nodes": [
[
"Image Scale Bounding Box",
@ -896,6 +917,15 @@
"title_aux": "IG Interpolation Nodes"
}
],
"https://github.com/Inzaniak/comfyui-ranbooru": [
[
"Ranbooru",
"RandomPicturePath"
],
{
"title_aux": "Ranbooru for ComfyUI"
}
],
"https://github.com/JPS-GER/ComfyUI_JPS-Nodes": [
[
"Conditioning Switch (JPS)",
@ -946,6 +976,44 @@
"title_aux": "JPS Custom Nodes for ComfyUI"
}
],
"https://github.com/JaredTherriault/ComfyUI-JNodes": [
[
"JNodes_AddOrSetPngInfoKey",
"JNodes_AppendReversedFrames",
"JNodes_BooleanSelectorWithString",
"JNodes_CheckpointSelectorWithString",
"JNodes_GetOutputDirectory",
"JNodes_GetParameterFromList",
"JNodes_GetParameterGlobal",
"JNodes_GetTempDirectory",
"JNodes_ImageFormatSelector",
"JNodes_ImageSizeSelector",
"JNodes_LoadVideo",
"JNodes_LoraExtractor",
"JNodes_OutVideoInfo",
"JNodes_ParseDynamicPrompts",
"JNodes_ParseParametersToGlobalList",
"JNodes_ParseWildcards",
"JNodes_PromptBuilderSingleSubject",
"JNodes_PromptEditor",
"JNodes_RemoveParseableDataForInference",
"JNodes_RemovePngInfoKey",
"JNodes_SamplerSelectorWithString",
"JNodes_SaveImageWithOutput",
"JNodes_SaveVideo",
"JNodes_SchedulerSelectorWithString",
"JNodes_SetNegativePromptInMetaData",
"JNodes_SetPositivePromptInMetaData",
"JNodes_StringLiteral",
"JNodes_SyncedStringLiteral",
"JNodes_TokenCounter",
"JNodes_UploadVideo",
"JNodes_VaeSelectorWithString"
],
{
"title_aux": "ComfyUI-JNodes"
}
],
"https://github.com/Jcd1230/rembg-comfyui-node": [
[
"Image Remove Background (rembg)"
@ -1065,6 +1133,7 @@
"VHS_MergeImages",
"VHS_MergeLatents",
"VHS_MergeMasks",
"VHS_PruneOutputs",
"VHS_SelectEveryNthImage",
"VHS_SelectEveryNthLatent",
"VHS_SelectEveryNthMask",
@ -1471,10 +1540,13 @@
"Cached Image Load From URL",
"Crop Center wigh SEGS",
"Crop Center with SEGS",
"Dilate Mask for Each Face",
"GW Number Formatting",
"Image Crop Fit",
"Image Resize Fit",
"OFF SEGS to Image",
"Query Gender and Age",
"Safe Mask to Image",
"VAE Encode For Inpaint V2",
"Watermarking"
],
@ -1560,7 +1632,11 @@
"ImageListSelect(FaceParsing)",
"ImagePadWithBBox(FaceParsing)",
"ImageResizeCalculator(FaceParsing)",
"ImageResizeWithBBox(FaceParsing)",
"ImageSize(FaceParsing)",
"LatentCropWithBBox(FaceParsing)",
"LatentInsertWithBBox(FaceParsing)",
"LatentSize(FaceParsing)",
"MaskComposite(FaceParsing)",
"MaskListComposite(FaceParsing)",
"MaskListSelect(FaceParsing)",
@ -1740,6 +1816,19 @@
"title_aux": "SDXL_sizing"
}
],
"https://github.com/Siberpone/lazy-pony-prompter": [
[
"LPP_Deleter",
"LPP_Derpibooru",
"LPP_E621",
"LPP_Loader_Derpibooru",
"LPP_Loader_E621",
"LPP_Saver"
],
{
"title_aux": "Lazy Pony Prompter"
}
],
"https://github.com/Smuzzies/comfyui_chatbox_overlay/raw/main/chatbox_overlay.py": [
[
"Chatbox Overlay"
@ -1785,16 +1874,8 @@
],
"https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes": [
[
"CR 3D Camera Drone",
"CR 3D Camera Static",
"CR 3D Polygon",
"CR 3D Solids",
"CR 8 Channel In",
"CR 8 Channel Out",
"CR ASCII Pattern",
"CR Add Annotation",
"CR Alternate Latents",
"CR Apply Annotations",
"CR Apply ControlNet",
"CR Apply LoRA Stack",
"CR Apply Model Merge",
@ -1804,13 +1885,13 @@
"CR Aspect Ratio",
"CR Aspect Ratio Banners",
"CR Aspect Ratio SDXL",
"CR Aspect Ratio Social Media",
"CR Batch Images From List",
"CR Batch Process Switch",
"CR Binary Pattern",
"CR Binary To Bit List",
"CR Bit Schedule",
"CR Central Schedule",
"CR Check Job Complete",
"CR Checker Pattern",
"CR Clamp Value",
"CR Clip Input Switch",
@ -1820,28 +1901,20 @@
"CR Color Tint",
"CR Combine Schedules",
"CR Comic Panel Templates",
"CR Comic Panel Templates (Advanced)",
"CR Comic Panel Templates Advanced",
"CR Composite Text",
"CR Conditioning Input Switch",
"CR Conditioning Mixer",
"CR Continuous Rotation",
"CR Continuous Track",
"CR Continuous Zoom",
"CR ControlNet Input Switch",
"CR Current Frame",
"CR Cycle Images",
"CR Cycle Images Simple",
"CR Cycle LoRAs",
"CR Cycle Models",
"CR Cycle Styles",
"CR Cycle Text",
"CR Cycle Text Simple",
"CR Data Bus In",
"CR Data Bus Out",
"CR Debatch Frames",
"CR Display Font",
"CR Draw OBJ",
"CR Draw Perspective Text",
"CR Draw Pie",
"CR Draw Shape",
@ -1870,7 +1943,6 @@
"CR Image Pipe In",
"CR Image Pipe Out",
"CR Image Size",
"CR Image Transition",
"CR Image XY Panel",
"CR Img2Img Process Switch",
"CR Increment Float",
@ -1884,19 +1956,11 @@
"CR Integer Range List",
"CR Integer To String",
"CR Interpolate Latents",
"CR Interpolate Prompt Weights",
"CR Interpolate Rotation",
"CR Interpolate Track",
"CR Interpolate Zoom",
"CR Intertwine Lists",
"CR Job Current Frame",
"CR Job List",
"CR Job Scheduler",
"CR KSampler",
"CR Keyframe List",
"CR Latent Batch Size",
"CR Latent Input Switch",
"CR List Schedule",
"CR LoRA List",
"CR LoRA Stack",
"CR Load Animation Frames",
@ -1911,9 +1975,6 @@
"CR Load Scheduled LoRAs",
"CR Load Scheduled Models",
"CR Load Text List",
"CR Load Workflow",
"CR Load XY Annotation From File",
"CR Loop List",
"CR Mask Text",
"CR Math Operation",
"CR Model Input Switch",
@ -1924,7 +1985,6 @@
"CR Module Pipe Loader",
"CR Multi Upscale Stack",
"CR Multi-ControlNet Stack",
"CR Multi-Panel Meme Template",
"CR Multiline Text",
"CR Output Flow Frames",
"CR Output Schedule To File",
@ -1933,14 +1993,11 @@
"CR Page Layout",
"CR Pipe Switch",
"CR Polygons",
"CR Popular Meme Templates",
"CR Prompt List",
"CR Prompt List Keyframes",
"CR Prompt Scheduler",
"CR Prompt Text",
"CR Prompt Weight Scheduler",
"CR Radial Gradient",
"CR Radial Gradient Map",
"CR Random Hex Color",
"CR Random LoRA Stack",
"CR Random Multiline Colors",
@ -1950,6 +2007,7 @@
"CR Random RGB Gradient",
"CR Random Shape Pattern",
"CR Random Weight LoRA",
"CR Repeater",
"CR SD1.5 Aspect Ratio",
"CR SDXL Aspect Ratio",
"CR SDXL Base Prompt Encoder",
@ -1957,24 +2015,23 @@
"CR SDXL Prompt Mixer",
"CR SDXL Style Text",
"CR Save Text To File",
"CR Schedule Camera Movements",
"CR Schedule ControlNets",
"CR Schedule Input Switch",
"CR Schedule Styles",
"CR Schedule To ScheduleList",
"CR Seamless Checker",
"CR Seed",
"CR Seed to Int",
"CR Select Font",
"CR Select ISO Size",
"CR Select Model",
"CR Select Resize Method",
"CR Set Switch From String",
"CR Set Value On Binary",
"CR Set Value On Boolean",
"CR Set Value on String",
"CR Simple Annotations",
"CR Simple Banner",
"CR Simple Binary Pattern",
"CR Simple Binary Pattern Simple",
"CR Simple Image Compare",
"CR Simple Image Watermark",
"CR Simple List",
"CR Simple Meme Template",
"CR Simple Prompt List",
@ -1986,25 +2043,22 @@
"CR Simple Text Watermark",
"CR Simple Titles",
"CR Simple Value Scheduler",
"CR Spawn Workflow Instance",
"CR Split String",
"CR Starburst Colors",
"CR Starburst Lines",
"CR String To Boolean",
"CR String To Combo",
"CR String To Number",
"CR Strobe Images",
"CR Style Bars",
"CR Style List",
"CR Switch Model and CLIP",
"CR System TrueType Font",
"CR Text",
"CR Text Blacklist",
"CR Text Concatenate",
"CR Text Cycler",
"CR Text Input Switch",
"CR Text Input Switch (4 way)",
"CR Text Length",
"CR Text List",
"CR Text List Cross Join",
"CR Text List Simple",
"CR Text List To String",
"CR Text Operation",
@ -2019,19 +2073,17 @@
"CR Value Scheduler",
"CR Vignette Filter",
"CR XY From Folder",
"CR XY Grid",
"CR XY Index",
"CR XY Interpolate",
"CR XY List",
"CR XY Product",
"CR XY Save Grid Image",
"CR XYZ Index",
"CR XYZ Interpolate",
"CR XYZ List"
"CR_Aspect Ratio For Print"
],
{
"author": "Suzie1",
"description": "169 custom nodes for artists, designers and animators.",
"description": "175 custom nodes for artists, designers and animators.",
"nickname": "Comfyroll Studio",
"title": "Comfyroll Studio",
"title_aux": "ComfyUI_Comfyroll_CustomNodes"
@ -2145,6 +2197,15 @@
"title_aux": "ComfyUI Prompt ExtraNetworks"
}
],
"https://github.com/Taremin/comfyui-string-tools": [
[
"StringToolsConcat",
"StringToolsRandomChoice"
],
{
"title_aux": "ComfyUI String Tools"
}
],
"https://github.com/TeaCrab/ComfyUI-TeaNodes": [
[
"TC_ColorFill",
@ -2259,8 +2320,6 @@
"0246.ScriptNode",
"0246.ScriptPile",
"0246.ScriptRule",
"0246.StrAdd",
"0246.StrAddBatch",
"0246.Stringify"
],
{
@ -2464,6 +2523,7 @@
"Integer place counter",
"KSampler (WAS)",
"KSampler Cycle",
"Latent Batch",
"Latent Input Switch",
"Latent Noise Injection",
"Latent Size to Number",
@ -2752,6 +2812,26 @@
"title_aux": "ComfyUI-AudioScheduler"
}
],
"https://github.com/abyz22/image_control": [
[
"abyz22_FirstNonNull",
"abyz22_FromBasicPipe_v2",
"abyz22_ImpactWildcardEncode",
"abyz22_ImpactWildcardEncode_GetPrompt",
"abyz22_Ksampler",
"abyz22_Padding Image",
"abyz22_SaveImage",
"abyz22_SetQueue",
"abyz22_ToBasicPipe",
"abyz22_blend_onecolor",
"abyz22_blendimages",
"abyz22_drawmask",
"abyz22_setimageinfo"
],
{
"title_aux": "image_control"
}
],
"https://github.com/adieyal/comfyui-dynamicprompts": [
[
"DPCombinatorialGenerator",
@ -2777,11 +2857,12 @@
"Aegisflow SDXL Tuple Pass",
"Aegisflow VAE Pass",
"Aegisflow controlnet preprocessor bus",
"Brightness & Contrast_Ally",
"Brightness_Contrast_Ally",
"Gaussian Blur_Ally",
"Image Flip_ally",
"Placeholder Tuple",
"aegisflow Multi_Pass"
"aegisflow Multi_Pass",
"aegisflow Multi_Pass XL"
],
{
"title_aux": "AegisFlow Utility Nodes"
@ -2806,7 +2887,7 @@
"https://github.com/alexopus/ComfyUI-Image-Saver": [
[
"Cfg Literal (Image Saver)",
"Checkpoint Selector (Image Saver)",
"Checkpoint Loader with Name (Image Saver)",
"Float Literal (Image Saver)",
"Image Saver",
"Int Literal (Image Saver)",
@ -3023,6 +3104,7 @@
"ImageBridge",
"LoadImageFromRequest",
"LoadImageWithAlpha",
"LoadValueFromRequest",
"SAM MultiLayer",
"Save Image With Workflow"
],
@ -3247,6 +3329,7 @@
"RGB to HSV",
"Rect Grab Cut",
"Remap",
"RemapFromQuadrilateral (homography)",
"RemapInsideParabolas",
"RemapInsideParabolasAdvanced",
"RemapToInnerCylinder",
@ -3415,12 +3498,42 @@
"https://github.com/chaojie/ComfyUI-DragNUWA": [
[
"DragNUWA Run",
"Load CheckPoint DragNUWA"
"Get First Image",
"Get Last Image",
"Load CheckPoint DragNUWA",
"Load Pose KeyPoints",
"Loop",
"LoopEnd_IMAGE",
"LoopStart_IMAGE",
"Split Tracking Points"
],
{
"title_aux": "ComfyUI-DragNUWA"
}
],
"https://github.com/chaojie/ComfyUI-I2VGEN-XL": [
[
"I2VGEN-XL Simple",
"Modelscope Pipeline Loader"
],
{
"title_aux": "ComfyUI-I2VGEN-XL"
}
],
"https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone": [
[
"Moore-AnimateAnyone Denoising Unet",
"Moore-AnimateAnyone Image Encoder",
"Moore-AnimateAnyone Pipeline Loader",
"Moore-AnimateAnyone Pose Guider",
"Moore-AnimateAnyone Reference Unet",
"Moore-AnimateAnyone Simple",
"Moore-AnimateAnyone VAE"
],
{
"title_aux": "ComfyUI-Moore-AnimateAnyone"
}
],
"https://github.com/chaojie/ComfyUI-MotionCtrl": [
[
"Load Motion Camera Preset",
@ -3435,6 +3548,27 @@
"title_aux": "ComfyUI-MotionCtrl"
}
],
"https://github.com/chaojie/ComfyUI-MotionCtrl-SVD": [
[
"Load Motionctrl-SVD Camera Preset",
"Load Motionctrl-SVD Checkpoint",
"Motionctrl-SVD Sample Simple"
],
{
"title_aux": "ComfyUI-MotionCtrl-SVD"
}
],
"https://github.com/chflame163/ComfyUI_LayerStyle": [
[
"LayerStyle_DropShadow",
"LayerStyle_ImageBlend",
"LayerStyle_ImageOpacity",
"LayerStyle_OuterGlow"
],
{
"title_aux": "ComfyUI Layer Style"
}
],
"https://github.com/chflame163/ComfyUI_MSSpeech_TTS": [
[
"Input Trigger",
@ -3449,7 +3583,8 @@
"https://github.com/chflame163/ComfyUI_WordCloud": [
[
"ComfyWordCloud",
"LoadTextFile"
"LoadTextFile",
"RGB_Picker"
],
{
"title_aux": "ComfyUI_WordCloud"
@ -3661,6 +3796,7 @@
"ImageCrop",
"ImageInvert",
"ImageOnlyCheckpointLoader",
"ImageOnlyCheckpointSave",
"ImagePadForOutpaint",
"ImageQuantize",
"ImageScale",
@ -3831,6 +3967,7 @@
"ExtractKeyframes+",
"GetImageSize+",
"ImageCASharpening+",
"ImageCompositeFromMaskBatch+",
"ImageCrop+",
"ImageDesaturate+",
"ImageEnhanceDifference+",
@ -3868,12 +4005,33 @@
"https://github.com/daniel-lewis-ab/ComfyUI-Llama": [
[
"Call LLM",
"Load LLM Model"
"LLM_Create_Embedding",
"LLM_Detokenize",
"LLM_Embed",
"LLM_Eval",
"LLM_Generate",
"LLM_Load_State",
"LLM_Reset",
"LLM_Sample",
"LLM_Save_State",
"LLM_Token_BOS",
"LLM_Token_EOS",
"LLM_Tokenize",
"Load LLM Model",
"Load LLM Model Advanced"
],
{
"title_aux": "ComfyUI-Llama"
}
],
"https://github.com/dave-palt/comfyui_DSP_imagehelpers": [
[
"dsp-imagehelpers-concat"
],
{
"title_aux": "comfyui_DSP_imagehelpers"
}
],
"https://github.com/dawangraoming/ComfyUI_ksampler_gpu/raw/main/ksampler_gpu.py": [
[
"KSamplerAdvancedGPU",
@ -4168,10 +4326,33 @@
],
"https://github.com/fexli/fexli-util-node-comfyui": [
[
"FEBCPrompt",
"FEBatchGenStringBCDocker",
"FEColor2Image",
"FEColorOut",
"FEDataInsertor",
"FEDataPacker",
"FEDataUnpacker",
"FEDeepClone",
"FEDictPacker",
"FEDictUnpacker",
"FEEncLoraLoader",
"FEExtraInfoAdd",
"FEGenStringBCDocker",
"FEGenStringGPT",
"FEImageNoiseGenerate",
"FEImagePadForOutpaint",
"FERandomizedColor2Image"
"FEImagePadForOutpaintByImage",
"FEOperatorIf",
"FEPythonStrOp",
"FERandomLoraSelect",
"FERandomPrompt",
"FERandomizedColor2Image",
"FERandomizedColorOut",
"FERerouteWithName",
"FESaveEncryptImage",
"FETextCombine",
"FETextInput"
],
{
"title_aux": "fexli-util-node-comfyui"
@ -4263,6 +4444,38 @@
"title_aux": "As_ComfyUI_CustomNodes"
}
],
"https://github.com/foxtrot-roger/comfyui-rf-nodes": [
[
"LogBool",
"LogFloat",
"LogInt",
"LogNumber",
"LogString",
"LogVec2",
"LogVec3",
"RF_BoolToString",
"RF_FloatToString",
"RF_IntToString",
"RF_JsonStyleLoader",
"RF_MergeLines",
"RF_NumberToString",
"RF_RangeFloat",
"RF_RangeInt",
"RF_RangeNumber",
"RF_SplitLines",
"RF_TextConcatenate",
"RF_TextInput",
"RF_TextReplace",
"RF_Timestamp",
"RF_ToString",
"RF_Vec2ToString",
"RF_Vec3ToString",
"TextLine"
],
{
"title_aux": "RF Nodes"
}
],
"https://github.com/gemell1/ComfyUI_GMIC": [
[
"GmicCliWrapper"
@ -4498,6 +4711,7 @@
"KSampler Adv. (Efficient)",
"KSampler SDXL (Eff.)",
"LatentUpscaler",
"LoRA Stack to String converter",
"LoRA Stacker",
"Manual XY Entry Info",
"NNLatentUpscale",
@ -4626,6 +4840,14 @@
"title_aux": "Knodes"
}
],
"https://github.com/kijai/ComfyUI-DDColor": [
[
"DDColor_Colorize"
],
{
"title_aux": "ComfyUI-DDColor"
}
],
"https://github.com/kijai/ComfyUI-KJNodes": [
[
"AddLabel",
@ -4781,7 +5003,15 @@
],
"https://github.com/komojini/komojini-comfyui-nodes": [
[
"FlowBuilder",
"Getter",
"ImageGetter",
"ImageMerger",
"KSamplerAdvancedCacheable",
"KSamplerCacheable",
"Setter",
"UltimateVideoLoader",
"UltimateVideoLoader (simple)",
"YouTubeVideoLoader"
],
{
@ -4860,7 +5090,9 @@
"Base64ToMask",
"ImageToBase64",
"ImageToBase64Advanced",
"LoadImageFromURL",
"LoadImageToBase64",
"LoadMaskFromURL",
"MaskImageToBase64",
"MaskToBase64",
"MaskToBase64Image",
@ -5092,7 +5324,9 @@
"InpaintPreprocessor_Provider_for_SEGS //Inspire",
"KSampler //Inspire",
"KSamplerAdvanced //Inspire",
"KSamplerAdvancedPipe //Inspire",
"KSamplerAdvancedProgress //Inspire",
"KSamplerPipe //Inspire",
"KSamplerProgress //Inspire",
"LatentBatchSplitter //Inspire",
"LeRes_DepthMap_Preprocessor_Provider_for_SEGS //Inspire",
@ -5128,6 +5362,7 @@
"RegionalSeedExplorerMask //Inspire",
"RemoveBackendData //Inspire",
"RemoveBackendDataNumberKey //Inspire",
"RemoveControlNet //Inspire",
"RetrieveBackendData //Inspire",
"RetrieveBackendDataNumberKey //Inspire",
"SeedExplorer //Inspire",
@ -5381,6 +5616,7 @@
[
"NegiTools_CompositeImages",
"NegiTools_DepthEstimationByMarigold",
"NegiTools_DetectFaceRotationForInpainting",
"NegiTools_ImageProperties",
"NegiTools_LatentProperties",
"NegiTools_NoiseImageGenerator",
@ -5415,6 +5651,15 @@
"title_aux": "comfyui-NDI"
}
],
"https://github.com/nkchocoai/ComfyUI-SizeFromPresets": [
[
"SizeFromPresetsSD15",
"SizeFromPresetsSDXL"
],
{
"title_aux": "ComfyUI-SizeFromPresets"
}
],
"https://github.com/noembryo/ComfyUI-noEmbryo": [
[
"PromptTermList1",
@ -5801,6 +6046,7 @@
"CombineMasks_",
"CombineSegMasks",
"DynamicDelayProcessor",
"EmbeddingPrompt",
"EnhanceImage",
"FaceToMask",
"FeatheredMask",
@ -5813,6 +6059,7 @@
"ImageColorTransfer",
"ImageCropByAlpha",
"IntNumber",
"JoinWithDelimiter",
"LaMaInpainting",
"LimitNumber",
"LoadImagesFromPath",
@ -5822,6 +6069,7 @@
"MultiplicationNode",
"NewLayer",
"NoiseImage",
"OutlineMask",
"PromptImage",
"PromptSimplification",
"PromptSlide",
@ -6165,6 +6413,7 @@
"GroundingDinoModelLoader (segment anything)",
"GroundingDinoSAMSegment (segment anything)",
"InvertMask (segment anything)",
"IsMaskEmpty",
"SAMModelLoader (segment anything)"
],
{
@ -6252,6 +6501,7 @@
],
"https://github.com/taabata/LCM_Inpaint-Outpaint_Comfy": [
[
"ComfyNodesToSaveCanvas",
"FloatNumber",
"FreeU_LCM",
"ImageOutputToComfyNodes",
@ -6298,7 +6548,8 @@
"https://github.com/talesofai/comfyui-browser": [
[
"LoadImageByUrl //Browser",
"SelectInputs //Browser"
"SelectInputs //Browser",
"XyzPlot //Browser"
],
{
"title_aux": "ComfyUI Browser"
@ -6395,6 +6646,7 @@
"Iterative Mixing KSampler Advanced",
"IterativeMixingSampler",
"IterativeMixingScheduler",
"IterativeMixingSchedulerAdvanced",
"Latent Batch Comparison Plot",
"Latent Batch Statistics Plot",
"MixingMaskGenerator"
@ -6726,6 +6978,8 @@
"easy XYInputs: ControlNet",
"easy XYInputs: Denoise",
"easy XYInputs: ModelMergeBlocks",
"easy XYInputs: NegativeCond",
"easy XYInputs: PositiveCond",
"easy XYInputs: PromptSR",
"easy XYInputs: Sampler/Scheduler",
"easy XYInputs: Seeds++ Batch",
@ -6747,13 +7001,14 @@
"easy imageSize",
"easy imageSizeByLongerSide",
"easy imageSizeBySide",
"easy imageToMask",
"easy kSampler",
"easy kSamplerDownscaleUnet",
"easy kSamplerInpainting",
"easy kSamplerSDTurbo",
"easy kSamplerTiled",
"easy latentCompositeMaskedWithCond",
"easy latentMultiplyBySigma",
"easy latentNoisy",
"easy loraStack",
"easy negative",
"easy pipeIn",
@ -6770,6 +7025,7 @@
"easy samLoaderPipe",
"easy seed",
"easy showSpentTime",
"easy stylesSelector",
"easy svdLoader",
"easy ultralyticsDetectorPipe",
"easy unSampler",

326
js/comfyui-manager.js vendored

@ -15,7 +15,8 @@ import { CustomNodesInstaller } from "./custom-nodes-downloader.js";
import { AlternativesInstaller } from "./a1111-alter-downloader.js";
import { SnapshotManager } from "./snapshot.js";
import { ModelInstaller } from "./model-downloader.js";
import { manager_instance, setManagerInstance, install_via_git_url, install_pip, rebootAPI, free_models } from "./common.js";
import { manager_instance, setManagerInstance, install_via_git_url, install_pip, rebootAPI, free_models } from "./common.js";
import { ComponentBuilderDialog, load_components, set_component_policy, getPureName } from "./components-manager.js";
var docStyle = document.createElement('style');
docStyle.innerHTML = `
@ -26,6 +27,35 @@ docStyle.innerHTML = `
z-index: 10000;
}
.cb-widget {
width: 400px;
height: 25px;
box-sizing: border-box;
z-index: 10000;
margin-top: 10px;
margin-bottom: 5px;
}
.cb-widget-input {
width: 305px;
height: 25px;
box-sizing: border-box;
}
.cb-widget-input:disabled {
background-color: #444444;
color: white;
}
.cb-widget-input-label {
width: 90px;
height: 25px;
box-sizing: border-box;
color: white;
text-align: right;
display: inline-block;
margin-right: 5px;
}
.cm-menu-container {
column-gap: 20px;
display: flex;
@ -71,6 +101,39 @@ docStyle.innerHTML = `
position: relative;
}
#custom-nodes-grid a {
color: #5555FF;
font-weight: bold;
text-decoration: none;
}
#custom-nodes-grid a:hover {
color: #7777FF;
text-decoration: underline;
}
#external-models-grid a {
color: #5555FF;
font-weight: bold;
text-decoration: none;
}
#external-models-grid a:hover {
color: #7777FF;
text-decoration: underline;
}
#alternatives-grid a {
color: #5555FF;
font-weight: bold;
text-decoration: none;
}
#alternatives-grid a:hover {
color: #7777FF;
text-decoration: underline;
}
.cm-notice-board {
width: 310px;
padding: 0px !important;
@ -217,6 +280,16 @@ const style = `
box-sizing: border-box;
}
.cb-node-label {
width: 400px;
height:28px;
color: black;
background-color: #777777;
font-size: 18px;
text-align: center;
font-weight: bold;
}
#cm-close-button {
width: calc(100% - 65px);
bottom: 10px;
@ -224,6 +297,16 @@ const style = `
overflow: hidden;
}
#cm-save-button {
width: calc(100% - 65px);
bottom:40px;
position: absolute;
overflow: hidden;
}
#cm-save-button:disabled {
background-color: #444444;
}
.pysssss-workflow-arrow-2 {
position: absolute;
top: 0;
@ -324,6 +407,15 @@ function getNickname(node, nodename) {
if (nicknames[nodename]) {
node.nickname = nicknames[nodename];
}
else if(node.getInnerNodes) {
let pure_name = getPureName(node);
let groupNode = app.graph.extra?.groupNodes?.[pure_name];
if(groupNode) {
let packname = groupNode.packname;
node.nickname = packname;
}
return node.nickname;
}
else {
for(let i in nickname_patterns) {
let item = nickname_patterns[i];
@ -638,6 +730,18 @@ class ManagerMenuDialog extends ComfyDialog {
}
}),
$el("button.cm-button", {
type: "button",
textContent: "Install via Git URL",
onclick: () => {
var url = prompt("Please enter the URL of the Git repository to install", "");
if (url !== null) {
install_via_git_url(url, self);
}
}
}),
$el("br", {}, []),
update_all_button,
update_comfyui_button,
@ -670,6 +774,7 @@ class ManagerMenuDialog extends ComfyDialog {
// db mode
this.datasrc_combo = document.createElement("select");
this.datasrc_combo.setAttribute("title", "Configure where to retrieve node/model information. If set to 'local,' the channel is ignored, and if set to 'channel (remote),' it fetches the latest information each time the list is opened.");
this.datasrc_combo.className = "cm-menu-combo";
this.datasrc_combo.appendChild($el('option', { value: 'cache', text: 'DB: Channel (1day cache)' }, []));
this.datasrc_combo.appendChild($el('option', { value: 'local', text: 'DB: Local' }, []));
@ -677,6 +782,7 @@ class ManagerMenuDialog extends ComfyDialog {
// preview method
let preview_combo = document.createElement("select");
preview_combo.setAttribute("title", "Configure how latent variables will be decoded during preview in the sampling process.");
preview_combo.className = "cm-menu-combo";
preview_combo.appendChild($el('option', { value: 'auto', text: 'Preview method: Auto' }, []));
preview_combo.appendChild($el('option', { value: 'taesd', text: 'Preview method: TAESD (slow)' }, []));
@ -693,6 +799,7 @@ class ManagerMenuDialog extends ComfyDialog {
// nickname
let badge_combo = document.createElement("select");
badge_combo.setAttribute("title", "Configure the content to be displayed on the badge at the top right corner of the node. The ID is the identifier of the node. If 'hide built-in' is selected, both unknown nodes and built-in nodes will be omitted, making them indistinguishable");
badge_combo.className = "cm-menu-combo";
badge_combo.appendChild($el('option', { value: 'none', text: 'Badge: None' }, []));
badge_combo.appendChild($el('option', { value: 'nick', text: 'Badge: Nickname' }, []));
@ -712,6 +819,7 @@ class ManagerMenuDialog extends ComfyDialog {
// channel
let channel_combo = document.createElement("select");
channel_combo.setAttribute("title", "Configure the channel for retrieving data from the Custom Node list (including missing nodes) or the Model list. Note that the badge utilizes local information.");
channel_combo.className = "cm-menu-combo";
api.fetchApi('/manager/channel_url_list')
.then(response => response.json())
@ -738,6 +846,7 @@ class ManagerMenuDialog extends ComfyDialog {
// default ui state
let default_ui_combo = document.createElement("select");
default_ui_combo.setAttribute("title", "Set the default state to be displayed in the main menu when the browser starts.");
default_ui_combo.className = "cm-menu-combo";
default_ui_combo.appendChild($el('option', { value: 'none', text: 'Default UI: None' }, []));
default_ui_combo.appendChild($el('option', { value: 'history', text: 'Default UI: History' }, []));
@ -753,6 +862,7 @@ class ManagerMenuDialog extends ComfyDialog {
// share
let share_combo = document.createElement("select");
share_combo.setAttribute("title", "Hide the share button in the main menu or set the default action upon clicking it. Additionally, configure the default share site when sharing via the context menu's share button.");
share_combo.className = "cm-menu-combo";
const share_options = [
['none', 'None'],
@ -766,6 +876,25 @@ class ManagerMenuDialog extends ComfyDialog {
share_combo.appendChild($el('option', { value: option[0], text: `Share: ${option[1]}` }, []));
}
// default ui state
let component_policy_combo = document.createElement("select");
component_policy_combo.setAttribute("title", "When loading the workflow, configure which version of the component to use.");
component_policy_combo.className = "cm-menu-combo";
component_policy_combo.appendChild($el('option', { value: 'workflow', text: 'Component: Use workflow version' }, []));
component_policy_combo.appendChild($el('option', { value: 'higher', text: 'Component: Use higher version' }, []));
component_policy_combo.appendChild($el('option', { value: 'mine', text: 'Component: Use my version' }, []));
api.fetchApi('/manager/component/policy')
.then(response => response.text())
.then(data => {
component_policy_combo.value = data;
set_component_policy(data);
});
component_policy_combo.addEventListener('change', function (event) {
api.fetchApi(`/manager/component/policy?value=${event.target.value}`);
set_component_policy(event.target.value);
});
api.fetchApi('/manager/share_option')
.then(response => response.text())
.then(data => {
@ -794,18 +923,8 @@ class ManagerMenuDialog extends ComfyDialog {
badge_combo,
default_ui_combo,
share_combo,
component_policy_combo,
$el("br", {}, []),
$el("button.cm-button", {
type: "button",
textContent: "Install via Git URL",
onclick: () => {
var url = prompt("Please enter the URL of the Git repository to install", "");
if (url !== null) {
install_via_git_url(url, self);
}
}
}),
$el("br", {}, []),
$el("filedset.cm-experimental", {}, [
@ -839,7 +958,7 @@ class ManagerMenuDialog extends ComfyDialog {
})
]),
];
}
}
createControlsRight() {
const elts = [
@ -891,12 +1010,12 @@ class ManagerMenuDialog extends ComfyDialog {
]),
$el("button", {
id: 'workflowgallery-button',
type: "button",
id: 'workflowgallery-button',
type: "button",
style: {
...(localStorage.getItem("wg_last_visited") ? {height: '50px'} : {})
...(localStorage.getItem("wg_last_visited") ? {height: '50px'} : {})
},
onclick: (e) => {
onclick: (e) => {
const last_visited_site = localStorage.getItem("wg_last_visited")
if (!!last_visited_site) {
window.open(last_visited_site, "comfyui-workflow-gallery");
@ -906,15 +1025,15 @@ class ManagerMenuDialog extends ComfyDialog {
},
}, [
$el("p", {
textContent: 'Workflow Gallery',
style: {
'text-align': 'center',
'color': 'white',
'font-size': '18px',
'margin': 0,
'padding': 0,
}
}, [
textContent: 'Workflow Gallery',
style: {
'text-align': 'center',
'color': 'white',
'font-size': '18px',
'margin': 0,
'padding': 0,
}
}, [
$el("p", {
id: 'workflowgallery-button-last-visited-label',
textContent: `(${localStorage.getItem("wg_last_visited") ? localStorage.getItem("wg_last_visited").split('/')[2] : ''})`,
@ -927,10 +1046,10 @@ class ManagerMenuDialog extends ComfyDialog {
}
})
]),
$el("div.pysssss-workflow-arrow-2", {
id: `comfyworkflows-button-arrow`,
onclick: this.handleWorkflowGalleryButtonClick
})
$el("div.pysssss-workflow-arrow-2", {
id: `comfyworkflows-button-arrow`,
onclick: this.handleWorkflowGalleryButtonClick
})
]),
$el("button.cm-button", {
@ -985,10 +1104,10 @@ class ManagerMenuDialog extends ComfyDialog {
this.element.style.display = "block";
}
handleWorkflowGalleryButtonClick(e) {
e.preventDefault();
e.stopPropagation();
LiteGraph.closeAllContextMenus();
handleWorkflowGalleryButtonClick(e) {
e.preventDefault();
e.stopPropagation();
LiteGraph.closeAllContextMenus();
// Modify the style of the button so that the UI can indicate the last
// visited site right away.
@ -999,72 +1118,72 @@ class ManagerMenuDialog extends ComfyDialog {
lastVisitedLabel.textContent = `(${url.split('/')[2]})`;
}
const menu = new LiteGraph.ContextMenu(
[
{
title: "Share your art",
callback: () => {
if (share_option === 'openart') {
showOpenArtShareDialog();
return;
} else if (share_option === 'matrix' || share_option === 'comfyworkflows') {
showShareDialog(share_option);
return;
} else if (share_option === 'youml') {
showYouMLShareDialog();
return;
}
if (!ShareDialogChooser.instance) {
ShareDialogChooser.instance = new ShareDialogChooser();
}
ShareDialogChooser.instance.show();
},
},
{
title: "Open 'openart.ai'",
const menu = new LiteGraph.ContextMenu(
[
{
title: "Share your art",
callback: () => {
if (share_option === 'openart') {
showOpenArtShareDialog();
return;
} else if (share_option === 'matrix' || share_option === 'comfyworkflows') {
showShareDialog(share_option);
return;
} else if (share_option === 'youml') {
showYouMLShareDialog();
return;
}
if (!ShareDialogChooser.instance) {
ShareDialogChooser.instance = new ShareDialogChooser();
}
ShareDialogChooser.instance.show();
},
},
{
title: "Open 'openart.ai'",
callback: () => {
const url = "https://openart.ai/workflows/dev";
localStorage.setItem("wg_last_visited", url);
window.open(url, "comfyui-workflow-gallery");
modifyButtonStyle(url);
},
},
{
title: "Open 'youml.com'",
callback: () => {
const url = "https://youml.com/?from=comfyui-share";
localStorage.setItem("wg_last_visited", url);
window.open(url, "comfyui-workflow-gallery");
modifyButtonStyle(url);
},
},
{
title: "Open 'comfyworkflows.com'",
callback: () => {
},
{
title: "Open 'youml.com'",
callback: () => {
const url = "https://youml.com/?from=comfyui-share";
localStorage.setItem("wg_last_visited", url);
window.open(url, "comfyui-workflow-gallery");
modifyButtonStyle(url);
},
},
{
title: "Open 'comfyworkflows.com'",
callback: () => {
const url = "https://comfyworkflows.com/";
localStorage.setItem("wg_last_visited", url);
window.open(url, "comfyui-workflow-gallery");
window.open(url, "comfyui-workflow-gallery");
modifyButtonStyle(url);
},
},
{
title: "Close",
callback: () => {
LiteGraph.closeAllContextMenus();
},
}
],
{
event: e,
scale: 1.3,
},
window
);
// set the id so that we can override the context menu's z-index to be above the comfyui manager menu
menu.root.id = "workflowgallery-button-menu";
menu.root.classList.add("pysssss-workflow-popup-2");
}
},
},
{
title: "Close",
callback: () => {
LiteGraph.closeAllContextMenus();
},
}
],
{
event: e,
scale: 1.3,
},
window
);
// set the id so that we can override the context menu's z-index to be above the comfyui manager menu
menu.root.id = "workflowgallery-button-menu";
menu.root.classList.add("pysssss-workflow-popup-2");
}
}
@ -1077,6 +1196,14 @@ app.registerExtension({
});
},
async setup() {
let orig_clear = app.graph.clear;
app.graph.clear = function () {
orig_clear.call(app.graph);
load_components();
};
load_components();
const menu = document.querySelector(".comfy-menu");
const separator = document.createElement("hr");
@ -1129,6 +1256,7 @@ app.registerExtension({
async beforeRegisterNodeDef(nodeType, nodeData, app) {
this._addExtraNodeContextMenu(nodeType, app);
},
async nodeCreated(node, app) {
if(!node.badge_enabled) {
node.getNickname = function () { return getNickname(node, node.comfyClass.trim()) };
@ -1139,6 +1267,7 @@ app.registerExtension({
node.badge_enabled = true;
}
},
async loadedGraphNode(node, app) {
if(!node.badge_enabled) {
const orig = node.onDrawForeground;
@ -1149,8 +1278,23 @@ app.registerExtension({
_addExtraNodeContextMenu(node, app) {
const origGetExtraMenuOptions = node.prototype.getExtraMenuOptions;
node.prototype.cm_menu_added = true;
node.prototype.getExtraMenuOptions = function (_, options) {
origGetExtraMenuOptions?.apply?.(this, arguments);
if (node.category.startsWith('group nodes/')) {
options.push({
content: "Save As Component",
callback: (obj) => {
if (!ComponentBuilderDialog.instance) {
ComponentBuilderDialog.instance = new ComponentBuilderDialog();
}
ComponentBuilderDialog.instance.target_node = node;
ComponentBuilderDialog.instance.show();
}
}, null);
}
if (isOutputNode(node)) {
const { potential_outputs } = getPotentialOutputsAndOutputNodes([this]);
const hasOutput = potential_outputs.length > 0;

13
js/common.js

@ -1,5 +1,5 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
import { api } from "../../scripts/api.js";
export async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
@ -48,8 +48,7 @@ export async function install_checked_custom_node(grid_rows, target_i, caller, m
});
if(response.status == 400) {
app.ui.dialog.show(`${mode} failed: ${target.title}`);
app.ui.dialog.element.style.zIndex = 10010;
show_message(`${mode} failed: ${target.title}`);
continue;
}
@ -64,8 +63,7 @@ export async function install_checked_custom_node(grid_rows, target_i, caller, m
}
if(failed != '') {
app.ui.dialog.show(`${mode} failed: ${failed}`);
app.ui.dialog.element.style.zIndex = 10010;
show_message(`${mode} failed: ${failed}`);
}
await caller.invalidateControl();
@ -160,4 +158,9 @@ export async function free_models() {
app.ui.dialog.show('Unloading of models failed.<BR><BR>Installed ComfyUI may be an outdated version.')
}
app.ui.dialog.element.style.zIndex = 10010;
}
export function show_message(msg) {
app.ui.dialog.show(msg);
app.ui.dialog.element.style.zIndex = 10010;
}

801
js/components-manager.js

@ -0,0 +1,801 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
import { sleep, show_message } from "./common.js";
import { GroupNodeConfig, GroupNodeHandler } from "../../extensions/core/groupNode.js";
import { ComfyDialog, $el } from "../../scripts/ui.js";
let pack_map = {};
let rpack_map = {};
export function getPureName(node) {
// group nodes/
let category = null;
if(node.category) {
category = node.category.substring(12);
}
else {
category = node.constructor.category?.substring(12);
}
if(category) {
let purename = node.comfyClass.substring(category.length+1);
return purename;
}
else if(node.comfyClass.startsWith('workflow/')) {
return node.comfyClass.substring(9);
}
else {
return node.comfyClass;
}
}
function isValidVersionString(version) {
const versionPattern = /^(\d+)\.(\d+)(\.(\d+))?$/;
const match = version.match(versionPattern);
return match !== null &&
parseInt(match[1], 10) >= 0 &&
parseInt(match[2], 10) >= 0 &&
(!match[3] || parseInt(match[4], 10) >= 0);
}
function register_pack_map(name, data) {
if(data.packname) {
pack_map[data.packname] = name;
rpack_map[name] = data;
}
else {
rpack_map[name] = data;
}
}
function storeGroupNode(name, data, register=true) {
let extra = app.graph.extra;
if (!extra) app.graph.extra = extra = {};
let groupNodes = extra.groupNodes;
if (!groupNodes) extra.groupNodes = groupNodes = {};
groupNodes[name] = data;
if(register) {
register_pack_map(name, data);
}
}
export async function load_components() {
let data = await api.fetchApi('/manager/component/loads', {method: "POST"});
let components = await data.json();
let start_time = Date.now();
let failed = [];
let failed2 = [];
for(let name in components) {
if(app.graph.extra?.groupNodes?.[name]) {
if(data) {
let data = components[name];
let category = data.packname;
if(data.category) {
category += "/" + data.category;
}
if(category == '') {
category = 'components';
}
const config = new GroupNodeConfig(name, data);
await config.registerType(category);
register_pack_map(name, data);
break;
}
continue;
}
let nodeData = components[name];
storeGroupNode(name, nodeData);
const config = new GroupNodeConfig(name, nodeData);
while(true) {
try {
let category = nodeData.packname;
if(nodeData.category) {
category += "/" + nodeData.category;
}
if(category == '') {
category = 'components';
}
await config.registerType(category);
register_pack_map(name, nodeData);
break;
}
catch {
let elapsed_time = Date.now() - start_time;
if (elapsed_time > 5000) {
failed.push(name);
break;
} else {
await sleep(100);
}
}
}
}
// fallback1
for(let i in failed) {
let name = failed[i];
if(app.graph.extra?.groupNodes?.[name]) {
continue;
}
let nodeData = components[name];
storeGroupNode(name, nodeData);
const config = new GroupNodeConfig(name, nodeData);
while(true) {
try {
let category = nodeData.packname;
if(nodeData.workflow.category) {
category += "/" + nodeData.category;
}
if(category == '') {
category = 'components';
}
await config.registerType(category);
register_pack_map(name, nodeData);
break;
}
catch {
let elapsed_time = Date.now() - start_time;
if (elapsed_time > 10000) {
failed2.push(name);
break;
} else {
await sleep(100);
}
}
}
}
// fallback2
for(let name in failed2) {
let name = failed2[i];
let nodeData = components[name];
storeGroupNode(name, nodeData);
const config = new GroupNodeConfig(name, nodeData);
while(true) {
try {
let category = nodeData.workflow.packname;
if(nodeData.workflow.category) {
category += "/" + nodeData.category;
}
if(category == '') {
category = 'components';
}
await config.registerType(category);
register_pack_map(name, nodeData);
break;
}
catch {
let elapsed_time = Date.now() - start_time;
if (elapsed_time > 30000) {
failed.push(name);
break;
} else {
await sleep(100);
}
}
}
}
}
async function save_as_component(node, version, prefix, nodename, packname, category) {
let component_name = `${prefix}::${nodename}`;
let subgraph = app.graph.extra?.groupNodes?.[component_name];
if(!subgraph) {
subgraph = app.graph.extra?.groupNodes?.[getPureName(node)];
}
subgraph.version = version;
subgraph.datetime = Date.now();
subgraph.packname = packname;
subgraph.category = category;
let body =
{
name: component_name,
workflow: subgraph
};
pack_map[packname] = component_name;
rpack_map[component_name] = subgraph;
const res = await api.fetchApi('/manager/component/save', {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if(res.status == 200) {
storeGroupNode(component_name, subgraph);
const config = new GroupNodeConfig(component_name, subgraph);
let category = body.workflow.packname;
if(body.workflow.category) {
category += "/" + body.workflow.category;
}
if(category == '') {
category = 'components';
}
await config.registerType(category);
let path = await res.text();
show_message(`Component '${component_name}' is saved into:\n${path}`);
}
else
show_message(`Failed to save component.`);
}
async function import_component(component_name, component, mode) {
if(mode) {
let body =
{
name: component_name,
workflow: component
};
const res = await api.fetchApi('/manager/component/save', {
method: "POST",
headers: { "Content-Type": "application/json", },
body: JSON.stringify(body)
});
}
let category = component.packname;
if(component.category) {
category += "/" + component.category;
}
if(category == '') {
category = 'components';
}
storeGroupNode(component_name, component);
const config = new GroupNodeConfig(component_name, component);
await config.registerType(category);
}
function restore_to_loaded_component(component_name) {
if(rpack_map[component_name]) {
let component = rpack_map[component_name];
storeGroupNode(component_name, component, false);
const config = new GroupNodeConfig(component_name, component);
config.registerType(component.category);
}
}
// Using a timestamp prevents duplicate pastes and ensures the prevention of re-deletion of litegrapheditor_clipboard.
let last_paste_timestamp = null;
function versionCompare(v1, v2) {
let ver1;
let ver2;
if(v1 && v1 != '') {
ver1 = v1.split('.');
ver1[0] = parseInt(ver1[0]);
ver1[1] = parseInt(ver1[1]);
if(ver1.length == 2)
ver1.push(0);
else
ver1[2] = parseInt(ver2[2]);
}
else {
ver1 = [0,0,0];
}
if(v2 && v2 != '') {
ver2 = v2.split('.');
ver2[0] = parseInt(ver2[0]);
ver2[1] = parseInt(ver2[1]);
if(ver2.length == 2)
ver2.push(0);
else
ver2[2] = parseInt(ver2[2]);
}
else {
ver2 = [0,0,0];
}
if(ver1[0] > ver2[0])
return -1;
else if(ver1[0] < ver2[0])
return 1;
if(ver1[1] > ver2[1])
return -1;
else if(ver1[1] < ver2[1])
return 1;
if(ver1[2] > ver2[2])
return -1;
else if(ver1[2] < ver2[2])
return 1;
return 0;
}
function checkVersion(name, component) {
let msg = '';
if(rpack_map[name]) {
let old_version = rpack_map[name].version;
if(!old_version || old_version == '') {
msg = ` '${name}' Upgrade (V0.0 -> V${component.version})`;
}
else {
let c = versionCompare(old_version, component.version);
if(c < 0) {
msg = ` '${name}' Downgrade (V${old_version} -> V${component.version})`;
}
else if(c > 0) {
msg = ` '${name}' Upgrade (V${old_version} -> V${component.version})`;
}
else {
msg = ` '${name}' Same version (V${component.version})`;
}
}
}
else {
msg = `'${name}' NEW (V${component.version})`;
}
return msg;
}
function handle_import_components(components) {
let msg = 'Components:\n';
let cnt = 0;
for(let name in components) {
let component = components[name];
let v = checkVersion(name, component);
if(cnt < 10) {
msg += v + '\n';
}
else if (cnt == 10) {
msg += '...\n';
}
else {
// do nothing
}
cnt++;
}
let last_name = null;
msg += '\nWill you load components?\n';
if(confirm(msg)) {
let mode = confirm('\nWill you save components?\n(cancel=load without save)');
for(let name in components) {
let component = components[name];
import_component(name, component, mode);
last_name = name;
}
if(mode) {
show_message('Components are saved.');
}
else {
show_message('Components are loaded.');
}
}
if(cnt == 1 && last_name) {
const node = LiteGraph.createNode(`workflow/${last_name}`);
node.pos = [app.canvas.graph_mouse[0], app.canvas.graph_mouse[1]];
app.canvas.graph.add(node, false);
}
}
function handlePaste(e) {
let data = (e.clipboardData || window.clipboardData);
const items = data.items;
for(const item of items) {
if(item.kind == 'string' && item.type == 'text/plain') {
data = data.getData("text/plain");
try {
let json_data = JSON.parse(data);
if(json_data.kind == 'ComfyUI Components' && last_paste_timestamp != json_data.timestamp) {
last_paste_timestamp = json_data.timestamp;
handle_import_components(json_data.components);
// disable paste node
localStorage.removeItem("litegrapheditor_clipboard", null);
}
else {
console.log('This components are already pasted: ignored');
}
}
catch {
// nothing to do
}
}
}
}
document.addEventListener("paste", handlePaste);
export class ComponentBuilderDialog extends ComfyDialog {
constructor() {
super();
}
clear() {
while (this.element.children.length) {
this.element.removeChild(this.element.children[0]);
}
}
show() {
this.invalidateControl();
this.element.style.display = "block";
this.element.style.zIndex = 10001;
this.element.style.width = "500px";
this.element.style.height = "450px";
}
invalidateControl() {
this.clear();
let self = this;
const close_button = $el("button", { id: "cm-close-button", type: "button", textContent: "Close", onclick: () => self.close() });
this.save_button = $el("button",
{ id: "cm-save-button", type: "button", textContent: "Save", onclick: () =>
{
save_as_component(self.target_node, self.version_string.value.trim(), self.node_prefix.value.trim(),
self.getNodeName(), self.getPackName(), self.category.value.trim());
}
});
let default_nodename = getPureName(this.target_node).trim();
let groupNode = app.graph.extra.groupNodes[default_nodename];
let default_packname = groupNode.packname;
if(!default_packname) {
default_packname = '';
}
let default_category = groupNode.category;
if(!default_category) {
default_category = '';
}
this.default_ver = groupNode.version;
if(!this.default_ver) {
this.default_ver = '0.0';
}
let delimiterIndex = default_nodename.indexOf('::');
let default_prefix = "";
if(delimiterIndex != -1) {
default_prefix = default_nodename.substring(0, delimiterIndex);
default_nodename = default_nodename.substring(delimiterIndex + 2);
}
if(!default_prefix) {
this.save_button.disabled = true;
}
this.pack_list = this.createPackListCombo();
let version_string = this.createLabeledInput('input version (e.g. 1.0)', '*Version : ', this.default_ver);
this.version_string = version_string[1];
this.version_string.disabled = true;
let node_prefix = this.createLabeledInput('input node prefix (e.g. mypack)', '*Prefix : ', default_prefix);
this.node_prefix = node_prefix[1];
let manual_nodename = this.createLabeledInput('input node name (e.g. MAKE_BASIC_PIPE)', 'Nodename : ', default_nodename);
this.manual_nodename = manual_nodename[1];
let manual_packname = this.createLabeledInput('input pack name (e.g. mypack)', 'Packname : ', default_packname);
this.manual_packname = manual_packname[1];
let category = this.createLabeledInput('input category (e.g. util/pipe)', 'Category : ', default_category);
this.category = category[1];
this.node_label = this.createNodeLabel();
let author_mode = this.createAuthorModeCheck();
this.author_mode = author_mode[0];
const content =
$el("div.comfy-modal-content",
[
$el("tr.cm-title", {}, [
$el("font", {size:6, color:"white"}, [`ComfyUI-Manager: Component Builder`])]
),
$el("br", {}, []),
$el("div.cm-menu-container",
[
author_mode[0],
author_mode[1],
category[0],
node_prefix[0],
manual_nodename[0],
manual_packname[0],
version_string[0],
this.pack_list,
$el("br", {}, []),
this.node_label
]),
$el("br", {}, []),
this.save_button,
close_button,
]
);
content.style.width = '100%';
content.style.height = '100%';
this.element = $el("div.comfy-modal", { id:'cm-manager-dialog', parent: document.body }, [ content ]);
}
validateInput() {
let msg = "";
if(!isValidVersionString(this.version_string.value)) {
msg += 'Invalid version string: '+event.value+"\n";
}
if(this.node_prefix.value.trim() == '') {
msg += 'Node prefix cannot be empty\n';
}
if(this.manual_nodename.value.trim() == '') {
msg += 'Node name cannot be empty\n';
}
if(msg != '') {
// alert(msg);
}
this.save_button.disabled = msg != "";
}
getPackName() {
if(this.pack_list.selectedIndex == 0) {
return this.manual_packname.value.trim();
}
return this.pack_list.value.trim();
}
getNodeName() {
if(this.manual_nodename.value.trim() != '') {
return this.manual_nodename.value.trim();
}
return getPureName(this.target_node);
}
createAuthorModeCheck() {
let check = $el("input",{type:'checkbox', id:"author-mode"},[])
const check_label = $el("label",{for:"author-mode"},["Enable author mode"]);
check_label.style.color = "var(--fg-color)";
check_label.style.cursor = "pointer";
check.checked = false;
let self = this;
check.onchange = () => {
self.version_string.disabled = !check.checked;
if(!check.checked) {
self.version_string.value = self.default_ver;
}
else {
alert('If you are not the author, it is not recommended to change the version, as it may cause component update issues.');
}
};
return [check, check_label];
}
createNodeLabel() {
let label = $el('p');
label.className = 'cb-node-label';
if(this.target_node.comfyClass.includes('::'))
label.textContent = getPureName(this.target_node);
else
label.textContent = " _::" + getPureName(this.target_node);
return label;
}
createLabeledInput(placeholder, label, value) {
let textbox = $el('input.cb-widget-input', {type:'text', placeholder:placeholder, value:value}, []);
let self = this;
textbox.onchange = () => {
this.validateInput.call(self);
this.node_label.textContent = this.node_prefix.value + "::" + this.manual_nodename.value;
}
let row = $el('span.cb-widget', {}, [ $el('span.cb-widget-input-label', label), textbox]);
return [row, textbox];
}
createPackListCombo() {
let combo = document.createElement("select");
combo.className = "cb-widget";
let default_packname_option = { value: '##manual', text: 'Packname: Manual' };
combo.appendChild($el('option', default_packname_option, []));
for(let name in pack_map) {
combo.appendChild($el('option', { value: name, text: 'Packname: '+ name }, []));
}
let self = this;
combo.onchange = function () {
if(combo.selectedIndex == 0) {
self.manual_packname.disabled = false;
}
else {
self.manual_packname.disabled = true;
}
};
return combo;
}
}
let orig_handleFile = app.handleFile;
function handleFile(file) {
if (file.name?.endsWith(".json") || file.name?.endsWith(".pack")) {
const reader = new FileReader();
reader.onload = async () => {
let is_component = false;
const jsonContent = JSON.parse(reader.result);
for(let name in jsonContent) {
let cand = jsonContent[name];
is_component = cand.datetime && cand.version;
break;
}
if(is_component) {
handle_import_components(jsonContent);
}
else {
orig_handleFile.call(app, file);
}
};
reader.readAsText(file);
return;
}
orig_handleFile.call(app, file);
}
app.handleFile = handleFile;
let current_component_policy = 'workflow';
try {
api.fetchApi('/manager/component/policy')
.then(response => response.text())
.then(data => { current_component_policy = data; });
}
catch {}
function getChangedVersion(groupNodes) {
if(!Object.keys(pack_map).length || !groupNodes)
return null;
let res = {};
for(let component_name in groupNodes) {
let data = groupNodes[component_name];
if(rpack_map[component_name]) {
let v = versionCompare(data.version, rpack_map[component_name].version);
res[component_name] = v;
}
}
return res;
}
const loadGraphData = app.loadGraphData;
app.loadGraphData = async function () {
if(arguments.length == 0)
return await loadGraphData.apply(this, arguments);
let graphData = arguments[0];
let groupNodes = graphData.extra?.groupNodes;
let res = getChangedVersion(groupNodes);
if(res) {
let target_components = null;
switch(current_component_policy) {
case 'higher':
target_components = Object.keys(res).filter(key => res[key] == 1);
break;
case 'mine':
target_components = Object.keys(res);
break;
default:
// do nothing
}
if(target_components) {
for(let i in target_components) {
let component_name = target_components[i];
let component = rpack_map[component_name];
if(component && graphData.extra?.groupNodes) {
graphData.extra.groupNodes[component_name] = component;
}
}
}
}
else {
console.log('Empty components: policy ignored');
}
arguments[0] = graphData;
return await loadGraphData.apply(this, arguments);
};
export function set_component_policy(v) {
current_component_policy = v;
}
let graphToPrompt = app.graphToPrompt;
app.graphToPrompt = async function () {
let p = await graphToPrompt.call(app);
try {
let groupNodes = p.workflow.extra?.groupNodes;
if(groupNodes) {
p.workflow.extra = { ... p.workflow.extra};
// get used group nodes
let used_group_nodes = new Set();
for(let node of p.workflow.nodes) {
if(node.type.startsWith('workflow/')) {
used_group_nodes.add(node.type.substring(9));
}
}
// remove unused group nodes
let new_groupNodes = {};
for (let key in p.workflow.extra.groupNodes) {
if (used_group_nodes.has(key)) {
new_groupNodes[key] = p.workflow.extra.groupNodes[key];
}
}
p.workflow.extra.groupNodes = new_groupNodes;
}
}
catch(e) {
console.log(`Failed to filtering group nodes: ${e}`);
}
return p;
}

60
js/snapshot.js

@ -6,7 +6,7 @@ import { manager_instance, rebootAPI } from "./common.js";
async function restore_snapshot(target) {
if(SnapshotManager.instance) {
try {
try {
const response = await api.fetchApi(`/snapshot/restore?target=${target}`, { cache: "no-store" });
if(response.status == 400) {
app.ui.dialog.show(`Restore snapshot failed: ${target.title} / ${exception}`);
@ -30,7 +30,7 @@ async function restore_snapshot(target) {
async function remove_snapshot(target) {
if(SnapshotManager.instance) {
try {
try {
const response = await api.fetchApi(`/snapshot/remove?target=${target}`, { cache: "no-store" });
if(response.status == 400) {
app.ui.dialog.show(`Remove snapshot failed: ${target.title} / ${exception}`);
@ -52,20 +52,20 @@ async function remove_snapshot(target) {
}
async function save_current_snapshot() {
try {
const response = await api.fetchApi('/snapshot/save', { cache: "no-store" });
app.ui.dialog.close();
return true;
}
catch(exception) {
app.ui.dialog.show(`Backup snapshot failed: ${exception}`);
app.ui.dialog.element.style.zIndex = 10010;
return false;
}
finally {
await SnapshotManager.instance.invalidateControl();
SnapshotManager.instance.updateMessage("<BR>Current snapshot saved.");
}
try {
const response = await api.fetchApi('/snapshot/save', { cache: "no-store" });
app.ui.dialog.close();
return true;
}
catch(exception) {
app.ui.dialog.show(`Backup snapshot failed: ${exception}`);
app.ui.dialog.element.style.zIndex = 10010;
return false;
}
finally {
await SnapshotManager.instance.invalidateControl();
SnapshotManager.instance.updateMessage("<BR>Current snapshot saved.");
}
}
async function getSnapshotList() {
@ -97,7 +97,7 @@ export class SnapshotManager extends ComfyDialog {
async remove_item() {
caller.disableButtons();
await caller.invalidateControl();
await caller.invalidateControl();
}
createControls() {
@ -151,14 +151,14 @@ export class SnapshotManager extends ComfyDialog {
var grid = document.createElement('table');
grid.setAttribute('id', 'snapshot-list-grid');
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
var headerRow = document.createElement('tr');
thead.style.position = "sticky";
thead.style.top = "0px";
thead.style.borderCollapse = "collapse";
thead.style.tableLayout = "fixed";
thead.style.borderCollapse = "collapse";
thead.style.tableLayout = "fixed";
var header1 = document.createElement('th');
header1.innerHTML = '&nbsp;&nbsp;ID&nbsp;&nbsp;';
@ -170,7 +170,7 @@ export class SnapshotManager extends ComfyDialog {
header_button.innerHTML = 'Action';
header_button.style.width = "100px";
thead.appendChild(headerRow);
thead.appendChild(headerRow);
headerRow.appendChild(header1);
headerRow.appendChild(header2);
headerRow.appendChild(header_button);
@ -231,17 +231,17 @@ export class SnapshotManager extends ComfyDialog {
this.grid_rows[i] = {data:data, control:dataRow};
}
let self = this;
let self = this;
const panel = document.createElement('div');
panel.style.width = "100%";
panel.style.width = "100%";
panel.appendChild(grid);
function handleResize() {
const parentHeight = self.element.clientHeight;
const gridHeight = parentHeight - 200;
function handleResize() {
const parentHeight = self.element.clientHeight;
const gridHeight = parentHeight - 200;
grid.style.height = gridHeight + "px";
}
grid.style.height = gridHeight + "px";
}
window.addEventListener("resize", handleResize);
grid.style.position = "relative";
@ -253,7 +253,7 @@ export class SnapshotManager extends ComfyDialog {
this.element.style.width = "80%";
this.element.appendChild(panel);
handleResize();
handleResize();
}
async createBottomControls() {

444
misc/Impact.pack

@ -0,0 +1,444 @@
{
"Impact::MAKE_BASIC_PIPE": {
"category": "",
"config": {
"1": {
"input": {
"text": {
"name": "Positive prompt"
}
}
},
"2": {
"input": {
"text": {
"name": "Negative prompt"
}
}
}
},
"datetime": 1705418802481,
"external": [],
"links": [
[
0,
1,
1,
0,
1,
"CLIP"
],
[
0,
1,
2,
0,
1,
"CLIP"
],
[
0,
0,
3,
0,
1,
"MODEL"
],
[
0,
1,
3,
1,
1,
"CLIP"
],
[
0,
2,
3,
2,
1,
"VAE"
],
[
1,
0,
3,
3,
3,
"CONDITIONING"
],
[
2,
0,
3,
4,
4,
"CONDITIONING"
]
],
"nodes": [
{
"flags": {},
"index": 0,
"mode": 0,
"order": 0,
"outputs": [
{
"links": [],
"name": "MODEL",
"shape": 3,
"slot_index": 0,
"type": "MODEL"
},
{
"links": [],
"name": "CLIP",
"shape": 3,
"slot_index": 1,
"type": "CLIP"
},
{
"links": [],
"name": "VAE",
"shape": 3,
"slot_index": 2,
"type": "VAE"
}
],
"pos": [
550,
360
],
"properties": {
"Node name for S&R": "CheckpointLoaderSimple"
},
"size": {
"0": 315,
"1": 98
},
"type": "CheckpointLoaderSimple",
"widgets_values": [
"SDXL/sd_xl_base_1.0_0.9vae.safetensors"
]
},
{
"flags": {},
"index": 1,
"inputs": [
{
"link": null,
"name": "clip",
"type": "CLIP"
}
],
"mode": 0,
"order": 1,
"outputs": [
{
"links": [],
"name": "CONDITIONING",
"shape": 3,
"slot_index": 0,
"type": "CONDITIONING"
}
],
"pos": [
940,
480
],
"properties": {
"Node name for S&R": "CLIPTextEncode"
},
"size": {
"0": 263,
"1": 99
},
"title": "Positive",
"type": "CLIPTextEncode",
"widgets_values": [
""
]
},
{
"flags": {},
"index": 2,
"inputs": [
{
"link": null,
"name": "clip",
"type": "CLIP"
}
],
"mode": 0,
"order": 2,
"outputs": [
{
"links": [],
"name": "CONDITIONING",
"shape": 3,
"slot_index": 0,
"type": "CONDITIONING"
}
],
"pos": [
940,
640
],
"properties": {
"Node name for S&R": "CLIPTextEncode"
},
"size": {
"0": 263,
"1": 99
},
"title": "Negative",
"type": "CLIPTextEncode",
"widgets_values": [
""
]
},
{
"flags": {},
"index": 3,
"inputs": [
{
"link": null,
"name": "model",
"type": "MODEL"
},
{
"link": null,
"name": "clip",
"type": "CLIP"
},
{
"link": null,
"name": "vae",
"type": "VAE"
},
{
"link": null,
"name": "positive",
"type": "CONDITIONING"
},
{
"link": null,
"name": "negative",
"type": "CONDITIONING"
}
],
"mode": 0,
"order": 3,
"outputs": [
{
"links": null,
"name": "basic_pipe",
"shape": 3,
"slot_index": 0,
"type": "BASIC_PIPE"
}
],
"pos": [
1320,
360
],
"properties": {
"Node name for S&R": "ToBasicPipe"
},
"size": {
"0": 241.79998779296875,
"1": 106
},
"type": "ToBasicPipe"
}
],
"packname": "Impact",
"version": "1.0"
},
"Impact::SIMPLE_DETAILER_PIPE": {
"category": "",
"config": {
"0": {
"output": {
"0": {
"visible": false
},
"1": {
"visible": false
}
}
},
"2": {
"input": {
"Select to add LoRA": {
"visible": false
},
"Select to add Wildcard": {
"visible": false
},
"wildcard": {
"visible": false
}
}
}
},
"datetime": 1705419147116,
"external": [],
"links": [
[
null,
0,
2,
0,
6,
"BASIC_PIPE"
],
[
0,
0,
2,
1,
13,
"BBOX_DETECTOR"
],
[
1,
0,
2,
2,
15,
"SAM_MODEL"
]
],
"nodes": [
{
"flags": {},
"index": 0,
"mode": 0,
"order": 2,
"outputs": [
{
"links": [],
"name": "BBOX_DETECTOR",
"shape": 3,
"type": "BBOX_DETECTOR"
},
{
"links": null,
"name": "SEGM_DETECTOR",
"shape": 3,
"type": "SEGM_DETECTOR"
}
],
"pos": [
590,
830
],
"properties": {
"Node name for S&R": "UltralyticsDetectorProvider"
},
"size": {
"0": 315,
"1": 78
},
"type": "UltralyticsDetectorProvider",
"widgets_values": [
"bbox/Eyeful_v1.pt"
]
},
{
"flags": {},
"index": 1,
"mode": 0,
"order": 3,
"outputs": [
{
"links": [],
"name": "SAM_MODEL",
"shape": 3,
"type": "SAM_MODEL"
}
],
"pos": [
590,
960
],
"properties": {
"Node name for S&R": "SAMLoader"
},
"size": {
"0": 315,
"1": 82
},
"type": "SAMLoader",
"widgets_values": [
"sam_vit_b_01ec64.pth",
"AUTO"
]
},
{
"flags": {},
"index": 2,
"inputs": [
{
"link": null,
"name": "basic_pipe",
"type": "BASIC_PIPE"
},
{
"link": null,
"name": "bbox_detector",
"slot_index": 1,
"type": "BBOX_DETECTOR"
},
{
"link": null,
"name": "sam_model_opt",
"slot_index": 2,
"type": "SAM_MODEL"
},
{
"link": null,
"name": "segm_detector_opt",
"type": "SEGM_DETECTOR"
},
{
"link": null,
"name": "detailer_hook",
"type": "DETAILER_HOOK"
}
],
"mode": 0,
"order": 5,
"outputs": [
{
"links": null,
"name": "detailer_pipe",
"shape": 3,
"type": "DETAILER_PIPE"
}
],
"pos": [
1044,
812
],
"properties": {
"Node name for S&R": "BasicPipeToDetailerPipe"
},
"size": {
"0": 400,
"1": 204
},
"type": "BasicPipeToDetailerPipe",
"widgets_values": [
"",
"Select the LoRA to add to the text",
"Select the Wildcard to add to the text"
]
}
],
"packname": "Impact",
"version": "1.0"
}
}

46
node_db/dev/custom-node-list.json

@ -9,7 +9,47 @@
"description": "If you see this message, your ComfyUI-Manager is outdated.\nDev channel provides only the list of the developing nodes. If you want to find the complete node list, please go to the Default channel."
},
{
"author": "chaojie",
"title": "LightGlue ⚡ [WIP]",
"reference": "https://github.com/chaojie/ComfyUI-LightGlue",
"files": [
"https://github.com/chaojie/ComfyUI-LightGlue"
],
"install_type": "git-clone",
"description": "This extension provides custom nodes for inference of LightGlue, a lightweight feature matcher with high accuracy and blazing fast inference. It takes as input a set of keypoints and descriptors for each image and returns the indices of corresponding points. The architecture is based on adaptive pruning techniques, in both network width and depth - [a/check out the paper for more details](https://arxiv.org/pdf/2306.13643.pdf)."
},
{
"author": "DimaChaichan",
"title": "LAizypainter-Exporter-ComfyUI [WIP]",
"reference": "https://github.com/DimaChaichan/LAizypainter-Exporter-ComfyUI",
"files": [
"https://github.com/DimaChaichan/LAizypainter-Exporter-ComfyUI"
],
"install_type": "git-clone",
"description": "WIP"
},
{
"author": "ZHO-ZHO-ZHO",
"title": "ComfyUI PhotoMaker (WIP)",
"reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker",
"files": [
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker"
],
"install_type": "git-clone",
"description": "Unofficial implementation of [a/PhotoMaker](https://github.com/TencentARC/PhotoMaker) for ComfyUI(WIP) Testing……"
},
{
"author": "poisenbery",
"title": "NudeNet-Detector-Provider [WIP]",
"reference": "https://github.com/poisenbery/NudeNet-Detector-Provider",
"files": [
"https://github.com/poisenbery/NudeNet-Detector-Provider"
],
"install_type": "git-clone",
"description": "BBOX Detector Provider for NudeNet. Bethesda version of NudeNet V3 detector provider to work with Impact Pack ComfyUI."
},
{
"author": "LarryJane491",
"title": "ComfyUI-ModelUnloader",
@ -23,9 +63,9 @@
{
"author": "AIGODLIKE",
"title": "AIGODLIKE/ComfyUI-Model-Manager [WIP]",
"reference": "https://github.com/AIGODLIKE/ComfyUI-Model-Manager",
"reference": "https://github.com/AIGODLIKE/ComfyUI-Studio",
"files": [
"https://github.com/AIGODLIKE/ComfyUI-Model-Manager"
"https://github.com/AIGODLIKE/ComfyUI-Studio"
],
"install_type": "git-clone",
"description": "WIP"

25
node_db/dev/extension-node-map.json

@ -61,6 +61,14 @@
"title_aux": "comfy-consistency-vae"
}
],
"https://github.com/LarryJane491/ComfyUI-ModelUnloader": [
[
"Model Unloader"
],
{
"title_aux": "ComfyUI-ModelUnloader"
}
],
"https://github.com/MrAdamBlack/CheckProgress": [
[
"CHECK_PROGRESS"
@ -114,6 +122,15 @@
"title_aux": "ComfyUI-AnyText\uff08WIP\uff09"
}
],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker": [
[
"PhotoMaker_Batch_Zho",
"PhotoMaker_Zho"
],
{
"title_aux": "ComfyUI PhotoMaker (WIP)"
}
],
"https://github.com/alt-key-project/comfyui-dream-video-batches": [
[
"Blended Transition [DVB]",
@ -624,6 +641,14 @@
"title_aux": "comfy-trt-test [WIP]"
}
],
"https://github.com/poisenbery/NudeNet-Detector-Provider": [
[
"NudeNetDetectorProvider"
],
{
"title_aux": "NudeNet-Detector-Provider [WIP]"
}
],
"https://github.com/solarpush/comfyui_sendimage_node": [
[
"Send_To_Pod"

352
node_db/new/custom-node-list.json

@ -9,7 +9,168 @@
"description": "If you see this message, your ComfyUI-Manager is outdated.\nRecent channel provides only the list of the latest nodes. If you want to find the complete node list, please go to the Default channel.\nMaking LoRA has never been easier!"
},
{
"author": "MrForExample",
"title": "ComfyUI-AnimateAnyone-Evolved",
"reference": "https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved",
"files": [
"https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved"
],
"install_type": "git-clone",
"description": "Improved [a/AnimateAnyone](https://github.com/HumanAIGC/AnimateAnyone) implementation that allows you to use the opse image sequence and reference image to generate stylized video."
},
{
"author": "chaojie",
"title": "ComfyUI-I2VGEN-XL",
"reference": "https://github.com/chaojie/ComfyUI-I2VGEN-XL",
"files": [
"https://github.com/chaojie/ComfyUI-I2VGEN-XL"
],
"install_type": "git-clone",
"description": "This is an implementation of [a/i2vgen-xl](https://github.com/ali-vilab/i2vgen-xl)"
},
{
"author": "Inzaniak",
"title": "Ranbooru for ComfyUI",
"reference": "https://github.com/Inzaniak/comfyui-ranbooru",
"files": [
"https://github.com/Inzaniak/comfyui-ranbooru"
],
"install_type": "git-clone",
"description": "Ranbooru is an extension for the comfyUI. The purpose of this extension is to add a node that gets a random set of tags from boorus pictures. This is mostly being used to help me test my checkpoints on a large variety of"
},
{
"author": "Taremin",
"title": "ComfyUI String Tools",
"reference": "https://github.com/Taremin/comfyui-string-tools",
"files": [
"https://github.com/Taremin/comfyui-string-tools"
],
"install_type": "git-clone",
"description": " This extension provides the StringToolsConcat node, which concatenates multiple texts, and the StringToolsRandomChoice node, which selects one randomly from multiple texts."
},
{
"author": "dave-palt",
"title": "comfyui_DSP_imagehelpers",
"reference": "https://github.com/dave-palt/comfyui_DSP_imagehelpers",
"files": [
"https://github.com/dave-palt/comfyui_DSP_imagehelpers"
],
"install_type": "git-clone",
"description": "Nodes: DSP Image Concat"
},
{
"author": "chaojie",
"title": "ComfyUI-Moore-AnimateAnyone",
"reference": "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone",
"files": [
"https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone"
],
"install_type": "git-clone",
"description": "Nodes: Run python tools/download_weights.py first to download weights automatically"
},
{
"author": "chflame163",
"title": "ComfyUI Layer Style",
"reference": "https://github.com/chflame163/ComfyUI_LayerStyle",
"files": [
"https://github.com/chflame163/ComfyUI_LayerStyle"
],
"install_type": "git-clone",
"description": "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress."
},
{
"author": "kijai",
"title": "ComfyUI-DDColor",
"reference": "https://github.com/kijai/ComfyUI-DDColor",
"files": [
"https://github.com/kijai/ComfyUI-DDColor"
],
"install_type": "git-clone",
"description": "Node to use [a/DDColor](https://github.com/piddnad/DDColor) in ComfyUI."
},
{
"author": "prozacgod",
"title": "ComfyUI Multi-Workspace",
"reference": "https://github.com/prozacgod/comfyui-pzc-multiworkspace",
"files": [
"https://github.com/prozacgod/comfyui-pzc-multiworkspace"
],
"install_type": "git-clone",
"description": "A simple, quick, and dirty implementation of multiple workspaces within ComfyUI."
},
{
"author": "Siberpone",
"title": "Lazy Pony Prompter",
"reference": "https://github.com/Siberpone/lazy-pony-prompter",
"files": [
"https://github.com/Siberpone/lazy-pony-prompter"
],
"install_type": "git-clone",
"description": "A pony prompt helper extension for AUTOMATIC1111's Stable Diffusion Web UI and ComfyUI that utilizes the full power of your favorite booru query syntax. Currently supports [a/Derpibooru](https://derpibooru/org) and [a/E621](https://e621.net/)."
},
{
"author": "chaojie",
"title": "ComfyUI-MotionCtrl-SVD",
"reference": "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD",
"files": [
"https://github.com/chaojie/ComfyUI-MotionCtrl-SVD"
],
"install_type": "git-clone",
"description": "Nodes: Download the weights of MotionCtrl-SVD [a/motionctrl_svd.ckpt](https://huggingface.co/TencentARC/MotionCtrl/blob/main/motionctrl_svd.ckpt) and put it to ComfyUI/models/checkpoints"
},
{
"author": "JaredTherriault",
"title": "ComfyUI-JNodes",
"reference": "https://github.com/JaredTherriault/ComfyUI-JNodes",
"files": [
"https://github.com/JaredTherriault/ComfyUI-JNodes"
],
"install_type": "git-clone",
"description": "python and web UX improvements for ComfyUI.\n[w/'DynamicPrompts.js' and 'EditAttention.js' from the core, along with 'ImageFeed.js' and 'favicon.js' from the custom scripts of pythongosssss, are not compatible. Therefore, manual deletion of these files is required to use this web extension.]"
},
{
"author": "nkchocoai",
"title": "ComfyUI-SizeFromPresets",
"reference": "https://github.com/nkchocoai/ComfyUI-SizeFromPresets",
"files": [
"https://github.com/nkchocoai/ComfyUI-SizeFromPresets"
],
"install_type": "git-clone",
"description": "Add a node that outputs width and height of the size selected from the preset (.csv)."
},
{
"author": "HAL41",
"title": "ComfyUI aichemy nodes",
"reference": "https://github.com/HAL41/ComfyUI-aichemy-nodes",
"files": [
"https://github.com/HAL41/ComfyUI-aichemy-nodes"
],
"install_type": "git-clone",
"description": "Simple node to handle scaling of YOLOv8 segmentation masks"
},
{
"author": "abyz22",
"title": "image_control",
"reference": "https://github.com/abyz22/image_control",
"files": [
"https://github.com/abyz22/image_control"
],
"install_type": "git-clone",
"description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor"
},
{
"author": "foxtrot-roger",
"title": "RF Nodes",
"reference": "https://github.com/foxtrot-roger/comfyui-rf-nodes",
"files": [
"https://github.com/foxtrot-roger/comfyui-rf-nodes"
],
"install_type": "git-clone",
"description": "A bunch of nodes that can be useful to manipulate primitive types (numbers, text, ...) Also some helpers to generate text and timestamps."
},
{
"author": "LarryJane491",
"title": "Lora-Training-in-Comfy",
@ -532,197 +693,6 @@
],
"install_type": "git-clone",
"description": "Nodes: Center Calculation. Improved Numerical Calculation for ComfyUI"
},
{
"author": "Comfyui_GPT_Story",
"title": "junglehu",
"reference": "https://github.com/junglehu/Comfyui_Story_LLmA",
"files": [
"https://github.com/junglehu/Comfyui_Story_LLmA"
],
"install_type": "git-clone",
"description": "GPT+Comfyui Generate coherent pictures"
},
{
"author": "HarroweD and quadmoon",
"title": "Harronode",
"reference": "https://github.com/NotHarroweD/Harronode",
"nodename_pattern": "Harronode",
"files": [
"https://github.com/NotHarroweD/Harronode.git"
],
"install_type": "git-clone",
"description": "Harronode is a custom node designed to build prompts easily for use with the Harrlogos SDXL LoRA. This Node simplifies the process of crafting prompts and makes all built in activation terms available at your fingertips."
},
{
"author": "styler00dollar",
"title": "ComfyUI-sudo-latent-upscale",
"reference": "https://github.com/styler00dollar/ComfyUI-sudo-latent-upscale",
"files": [
"https://github.com/styler00dollar/ComfyUI-sudo-latent-upscale"
],
"install_type": "git-clone",
"description": "Directly upscaling inside the latent space. Model was trained for SD1.5 and drawn content. Might add new architectures or update models at some point. This took heavy inspriration from [city96/SD-Latent-Upscaler](https://github.com/city96/SD-Latent-Upscaler) and [Ttl/ComfyUi_NNLatentUpscale](https://github.com/Ttl/ComfyUi_NNLatentUpscale). "
},
{
"author": "thecooltechguy",
"title": "ComfyUI-ComfyRun",
"reference": "https://github.com/thecooltechguy/ComfyUI-ComfyRun",
"files": [
"https://github.com/thecooltechguy/ComfyUI-ComfyRun"
],
"install_type": "git-clone",
"description": "The easiest way to run & share any ComfyUI workflow [a/https://comfyrun.com](https://comfyrun.com)"
},
{
"author": "ceruleandeep",
"title": "ComfyUI LLaVA Captioner",
"reference": "https://github.com/ceruleandeep/ComfyUI-LLaVA-Captioner",
"files": [
"https://github.com/ceruleandeep/ComfyUI-LLaVA-Captioner"
],
"install_type": "git-clone",
"description": "A ComfyUI extension for chatting with your images. Runs on your own system, no external services used, no filter. Uses the [a/LLaVA multimodal LLM](https://llava-vl.github.io/) so you can give instructions or ask questions in natural language. It's maybe as smart as GPT3.5, and it can see."
},
{
"author": "jitcoder",
"title": "LoraInfo",
"reference": "https://github.com/jitcoder/lora-info",
"files": [
"https://github.com/jitcoder/lora-info"
],
"install_type": "git-clone",
"description": "Shows Lora information from CivitAI and outputs trigger words and example prompt"
},
{
"author": "ttulttul",
"title": "ComfyUI Iterative Mixing Nodes",
"reference": "https://github.com/ttulttul/ComfyUI-Iterative-Mixer",
"files": [
"https://github.com/ttulttul/ComfyUI-Iterative-Mixer"
],
"install_type": "git-clone",
"description": "Nodes: Iterative Mixing KSampler, Batch Unsampler, Iterative Mixing KSampler Advanced"
},
{
"author": "OpenArt-AI",
"title": "ComfyUI Assistant",
"reference": "https://github.com/OpenArt-AI/ComfyUI-Assistant",
"files": [
"https://github.com/OpenArt-AI/ComfyUI-Assistant"
],
"install_type": "git-clone",
"description": "ComfyUI Assistant is your one stop plugin for everything you need to get started with comfy-ui. Now it provides useful courses, tutorials, and basic templates."
},
{
"author": "shockz0rz",
"title": "comfy-easy-grids",
"reference": "https://github.com/shockz0rz/comfy-easy-grids",
"files": [
"https://github.com/shockz0rz/comfy-easy-grids"
],
"install_type": "git-clone",
"description": "A set of custom nodes for creating image grids, sequences, and batches in ComfyUI."
},
{
"author": "CosmicLaca",
"title": "Primere nodes for ComfyUI",
"reference": "https://github.com/CosmicLaca/ComfyUI_Primere_Nodes",
"files": [
"https://github.com/CosmicLaca/ComfyUI_Primere_Nodes"
],
"install_type": "git-clone",
"description": "This extension provides various utility nodes. Inputs(prompt, styles, dynamic, merger, ...), Outputs(style pile), Dashboard(selectors, loader, switch, ...), Networks(LORA, Embedding, Hypernetwork), Visuals(visual selectors, )"
},
{
"author": "ZHO-ZHO-ZHO",
"title": "ComfyUI-Gemini",
"reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-Gemini",
"files": [
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-Gemini"
],
"install_type": "git-clone",
"description": "Using Gemini-pro & Gemini-pro-vision in ComfyUI."
},
{
"author": "ZHO-ZHO-ZHO",
"title": "comfyui-portrait-master-zh-cn",
"reference": "https://github.com/ZHO-ZHO-ZHO/comfyui-portrait-master-zh-cn",
"files": [
"https://github.com/ZHO-ZHO-ZHO/comfyui-portrait-master-zh-cn"
],
"install_type": "git-clone",
"description": "ComfyUI Portrait Master 简体中文版."
},
{
"author": "Continue7777",
"title": "comfyui-easyapi-nodes",
"reference": "https://github.com/Continue7777/comfyui-yoy",
"files": [
"https://github.com/Continue7777/comfyui-yoy"
],
"install_type": "git-clone",
"description": "This plugin gives you the ability to generate a real Product rendering, commonly referred to as the mockup.The most important is that we can provide it for you,cause we have a complete supply chain.You can buy products with your designs or sell them. We can provide you dropshipping services."
},
{
"author": "RenderRift",
"title": "ComfyUI-RenderRiftNodes",
"reference": "https://github.com/RenderRift/ComfyUI-RenderRiftNodes",
"files": [
"https://github.com/RenderRift/ComfyUI-RenderRiftNodes"
],
"install_type": "git-clone",
"description": "Nodes:RR_Date_Folder_Format, RR_Image_Metadata_Overlay, RR_VideoPathMetaExtraction, RR_DisplayMetaOptions. This extension provides nodes designed to enhance the Animatediff workflow."
},
{
"author": "Haoming02",
"title": "ComfyUI Floodgate",
"reference": "https://github.com/Haoming02/comfyui-floodgate",
"files": [
"https://github.com/Haoming02/comfyui-floodgate"
],
"install_type": "git-clone",
"description": "This is an Extension for ComfyUI, which allows you to control the logic flow with just one click!"
},
{
"author": "Trung0246",
"title": "ComfyUI-0246",
"reference": "https://github.com/Trung0246/ComfyUI-0246",
"files": [
"https://github.com/Trung0246/ComfyUI-0246"
],
"install_type": "git-clone",
"description": "Random nodes for ComfyUI I made to solve my struggle with ComfyUI (ex: pipe, process). Have varying quality."
},
{
"author": "violet-chen",
"title": "comfyui-psd2png",
"reference": "https://github.com/violet-chen/comfyui-psd2png",
"files": [
"https://github.com/violet-chen/comfyui-psd2png"
],
"install_type": "git-clone",
"description": "Nodes: Psd2Png."
},
{
"author": "IDGallagher",
"title": "IG Interpolation Nodes",
"reference": "https://github.com/IDGallagher/ComfyUI-IG-Nodes",
"files": [
"https://github.com/IDGallagher/ComfyUI-IG-Nodes"
],
"install_type": "git-clone",
"description": "Custom nodes to aid in the exploration of Latent Space"
},
{
"author": "rcfcu2000",
"title": "zhihuige-nodes-comfyui",
"reference": "https://github.com/rcfcu2000/zhihuige-nodes-comfyui",
"files": [
"https://github.com/rcfcu2000/zhihuige-nodes-comfyui"
],
"install_type": "git-clone",
"description": "Nodes: Combine ZHGMasks, Cover ZHGMasks, ZHG FaceIndex, ZHG SaveImage, ZHG SmoothEdge, ZHG GetMaskArea, ..."
}
]
}

374
node_db/new/extension-node-map.json

@ -116,8 +116,17 @@
[
"ApplyMaskToImage-badger",
"CropImageByMask-badger",
"ExpandImageWithColor-badger",
"FindThickLinesFromCanny-badger",
"FloatToInt-badger",
"FloatToString-badger",
"FrameToVideo-badger",
"GarbageCollect-badger",
"GetColorFromBorder-badger",
"GetDirName-badger",
"GetUUID-badger",
"IdentifyBorderColorToMask-badger",
"IdentifyColorToMask-badger",
"ImageNormalization-badger",
"ImageOverlap-badger",
"ImageScaleToSide-badger",
@ -125,7 +134,9 @@
"SegmentToMaskByPoint-badger",
"StringToFizz-badger",
"TextListToString-badger",
"VideoCut-badger",
"TrimTransparentEdges-badger",
"VideoCutFromDir-badger",
"VideoToFrame-badger",
"deleteDir-badger",
"findCenterOfMask-badger",
"getImageSide-badger",
@ -261,7 +272,9 @@
[
"ComfyUIDeployExternalImage",
"ComfyUIDeployExternalImageAlpha",
"ComfyUIDeployExternalLora",
"ComfyUIDeployExternalNumber",
"ComfyUIDeployExternalNumberInt",
"ComfyUIDeployExternalText"
],
{
@ -837,6 +850,14 @@
"title_aux": "ReActor Node for ComfyUI"
}
],
"https://github.com/HAL41/ComfyUI-aichemy-nodes": [
[
"aichemyYOLOv8Segmentation"
],
{
"title_aux": "ComfyUI aichemy nodes"
}
],
"https://github.com/Hangover3832/ComfyUI-Hangover-Nodes": [
[
"Image Scale Bounding Box",
@ -896,6 +917,15 @@
"title_aux": "IG Interpolation Nodes"
}
],
"https://github.com/Inzaniak/comfyui-ranbooru": [
[
"Ranbooru",
"RandomPicturePath"
],
{
"title_aux": "Ranbooru for ComfyUI"
}
],
"https://github.com/JPS-GER/ComfyUI_JPS-Nodes": [
[
"Conditioning Switch (JPS)",
@ -946,6 +976,44 @@
"title_aux": "JPS Custom Nodes for ComfyUI"
}
],
"https://github.com/JaredTherriault/ComfyUI-JNodes": [
[
"JNodes_AddOrSetPngInfoKey",
"JNodes_AppendReversedFrames",
"JNodes_BooleanSelectorWithString",
"JNodes_CheckpointSelectorWithString",
"JNodes_GetOutputDirectory",
"JNodes_GetParameterFromList",
"JNodes_GetParameterGlobal",
"JNodes_GetTempDirectory",
"JNodes_ImageFormatSelector",
"JNodes_ImageSizeSelector",
"JNodes_LoadVideo",
"JNodes_LoraExtractor",
"JNodes_OutVideoInfo",
"JNodes_ParseDynamicPrompts",
"JNodes_ParseParametersToGlobalList",
"JNodes_ParseWildcards",
"JNodes_PromptBuilderSingleSubject",
"JNodes_PromptEditor",
"JNodes_RemoveParseableDataForInference",
"JNodes_RemovePngInfoKey",
"JNodes_SamplerSelectorWithString",
"JNodes_SaveImageWithOutput",
"JNodes_SaveVideo",
"JNodes_SchedulerSelectorWithString",
"JNodes_SetNegativePromptInMetaData",
"JNodes_SetPositivePromptInMetaData",
"JNodes_StringLiteral",
"JNodes_SyncedStringLiteral",
"JNodes_TokenCounter",
"JNodes_UploadVideo",
"JNodes_VaeSelectorWithString"
],
{
"title_aux": "ComfyUI-JNodes"
}
],
"https://github.com/Jcd1230/rembg-comfyui-node": [
[
"Image Remove Background (rembg)"
@ -1065,6 +1133,7 @@
"VHS_MergeImages",
"VHS_MergeLatents",
"VHS_MergeMasks",
"VHS_PruneOutputs",
"VHS_SelectEveryNthImage",
"VHS_SelectEveryNthLatent",
"VHS_SelectEveryNthMask",
@ -1471,10 +1540,13 @@
"Cached Image Load From URL",
"Crop Center wigh SEGS",
"Crop Center with SEGS",
"Dilate Mask for Each Face",
"GW Number Formatting",
"Image Crop Fit",
"Image Resize Fit",
"OFF SEGS to Image",
"Query Gender and Age",
"Safe Mask to Image",
"VAE Encode For Inpaint V2",
"Watermarking"
],
@ -1560,7 +1632,11 @@
"ImageListSelect(FaceParsing)",
"ImagePadWithBBox(FaceParsing)",
"ImageResizeCalculator(FaceParsing)",
"ImageResizeWithBBox(FaceParsing)",
"ImageSize(FaceParsing)",
"LatentCropWithBBox(FaceParsing)",
"LatentInsertWithBBox(FaceParsing)",
"LatentSize(FaceParsing)",
"MaskComposite(FaceParsing)",
"MaskListComposite(FaceParsing)",
"MaskListSelect(FaceParsing)",
@ -1740,6 +1816,19 @@
"title_aux": "SDXL_sizing"
}
],
"https://github.com/Siberpone/lazy-pony-prompter": [
[
"LPP_Deleter",
"LPP_Derpibooru",
"LPP_E621",
"LPP_Loader_Derpibooru",
"LPP_Loader_E621",
"LPP_Saver"
],
{
"title_aux": "Lazy Pony Prompter"
}
],
"https://github.com/Smuzzies/comfyui_chatbox_overlay/raw/main/chatbox_overlay.py": [
[
"Chatbox Overlay"
@ -1785,16 +1874,8 @@
],
"https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes": [
[
"CR 3D Camera Drone",
"CR 3D Camera Static",
"CR 3D Polygon",
"CR 3D Solids",
"CR 8 Channel In",
"CR 8 Channel Out",
"CR ASCII Pattern",
"CR Add Annotation",
"CR Alternate Latents",
"CR Apply Annotations",
"CR Apply ControlNet",
"CR Apply LoRA Stack",
"CR Apply Model Merge",
@ -1804,13 +1885,13 @@
"CR Aspect Ratio",
"CR Aspect Ratio Banners",
"CR Aspect Ratio SDXL",
"CR Aspect Ratio Social Media",
"CR Batch Images From List",
"CR Batch Process Switch",
"CR Binary Pattern",
"CR Binary To Bit List",
"CR Bit Schedule",
"CR Central Schedule",
"CR Check Job Complete",
"CR Checker Pattern",
"CR Clamp Value",
"CR Clip Input Switch",
@ -1820,28 +1901,20 @@
"CR Color Tint",
"CR Combine Schedules",
"CR Comic Panel Templates",
"CR Comic Panel Templates (Advanced)",
"CR Comic Panel Templates Advanced",
"CR Composite Text",
"CR Conditioning Input Switch",
"CR Conditioning Mixer",
"CR Continuous Rotation",
"CR Continuous Track",
"CR Continuous Zoom",
"CR ControlNet Input Switch",
"CR Current Frame",
"CR Cycle Images",
"CR Cycle Images Simple",
"CR Cycle LoRAs",
"CR Cycle Models",
"CR Cycle Styles",
"CR Cycle Text",
"CR Cycle Text Simple",
"CR Data Bus In",
"CR Data Bus Out",
"CR Debatch Frames",
"CR Display Font",
"CR Draw OBJ",
"CR Draw Perspective Text",
"CR Draw Pie",
"CR Draw Shape",
@ -1870,7 +1943,6 @@
"CR Image Pipe In",
"CR Image Pipe Out",
"CR Image Size",
"CR Image Transition",
"CR Image XY Panel",
"CR Img2Img Process Switch",
"CR Increment Float",
@ -1884,19 +1956,11 @@
"CR Integer Range List",
"CR Integer To String",
"CR Interpolate Latents",
"CR Interpolate Prompt Weights",
"CR Interpolate Rotation",
"CR Interpolate Track",
"CR Interpolate Zoom",
"CR Intertwine Lists",
"CR Job Current Frame",
"CR Job List",
"CR Job Scheduler",
"CR KSampler",
"CR Keyframe List",
"CR Latent Batch Size",
"CR Latent Input Switch",
"CR List Schedule",
"CR LoRA List",
"CR LoRA Stack",
"CR Load Animation Frames",
@ -1911,9 +1975,6 @@
"CR Load Scheduled LoRAs",
"CR Load Scheduled Models",
"CR Load Text List",
"CR Load Workflow",
"CR Load XY Annotation From File",
"CR Loop List",
"CR Mask Text",
"CR Math Operation",
"CR Model Input Switch",
@ -1924,7 +1985,6 @@
"CR Module Pipe Loader",
"CR Multi Upscale Stack",
"CR Multi-ControlNet Stack",
"CR Multi-Panel Meme Template",
"CR Multiline Text",
"CR Output Flow Frames",
"CR Output Schedule To File",
@ -1933,14 +1993,11 @@
"CR Page Layout",
"CR Pipe Switch",
"CR Polygons",
"CR Popular Meme Templates",
"CR Prompt List",
"CR Prompt List Keyframes",
"CR Prompt Scheduler",
"CR Prompt Text",
"CR Prompt Weight Scheduler",
"CR Radial Gradient",
"CR Radial Gradient Map",
"CR Random Hex Color",
"CR Random LoRA Stack",
"CR Random Multiline Colors",
@ -1950,6 +2007,7 @@
"CR Random RGB Gradient",
"CR Random Shape Pattern",
"CR Random Weight LoRA",
"CR Repeater",
"CR SD1.5 Aspect Ratio",
"CR SDXL Aspect Ratio",
"CR SDXL Base Prompt Encoder",
@ -1957,24 +2015,23 @@
"CR SDXL Prompt Mixer",
"CR SDXL Style Text",
"CR Save Text To File",
"CR Schedule Camera Movements",
"CR Schedule ControlNets",
"CR Schedule Input Switch",
"CR Schedule Styles",
"CR Schedule To ScheduleList",
"CR Seamless Checker",
"CR Seed",
"CR Seed to Int",
"CR Select Font",
"CR Select ISO Size",
"CR Select Model",
"CR Select Resize Method",
"CR Set Switch From String",
"CR Set Value On Binary",
"CR Set Value On Boolean",
"CR Set Value on String",
"CR Simple Annotations",
"CR Simple Banner",
"CR Simple Binary Pattern",
"CR Simple Binary Pattern Simple",
"CR Simple Image Compare",
"CR Simple Image Watermark",
"CR Simple List",
"CR Simple Meme Template",
"CR Simple Prompt List",
@ -1986,25 +2043,22 @@
"CR Simple Text Watermark",
"CR Simple Titles",
"CR Simple Value Scheduler",
"CR Spawn Workflow Instance",
"CR Split String",
"CR Starburst Colors",
"CR Starburst Lines",
"CR String To Boolean",
"CR String To Combo",
"CR String To Number",
"CR Strobe Images",
"CR Style Bars",
"CR Style List",
"CR Switch Model and CLIP",
"CR System TrueType Font",
"CR Text",
"CR Text Blacklist",
"CR Text Concatenate",
"CR Text Cycler",
"CR Text Input Switch",
"CR Text Input Switch (4 way)",
"CR Text Length",
"CR Text List",
"CR Text List Cross Join",
"CR Text List Simple",
"CR Text List To String",
"CR Text Operation",
@ -2019,19 +2073,17 @@
"CR Value Scheduler",
"CR Vignette Filter",
"CR XY From Folder",
"CR XY Grid",
"CR XY Index",
"CR XY Interpolate",
"CR XY List",
"CR XY Product",
"CR XY Save Grid Image",
"CR XYZ Index",
"CR XYZ Interpolate",
"CR XYZ List"
"CR_Aspect Ratio For Print"
],
{
"author": "Suzie1",
"description": "169 custom nodes for artists, designers and animators.",
"description": "175 custom nodes for artists, designers and animators.",
"nickname": "Comfyroll Studio",
"title": "Comfyroll Studio",
"title_aux": "ComfyUI_Comfyroll_CustomNodes"
@ -2145,6 +2197,15 @@
"title_aux": "ComfyUI Prompt ExtraNetworks"
}
],
"https://github.com/Taremin/comfyui-string-tools": [
[
"StringToolsConcat",
"StringToolsRandomChoice"
],
{
"title_aux": "ComfyUI String Tools"
}
],
"https://github.com/TeaCrab/ComfyUI-TeaNodes": [
[
"TC_ColorFill",
@ -2259,8 +2320,6 @@
"0246.ScriptNode",
"0246.ScriptPile",
"0246.ScriptRule",
"0246.StrAdd",
"0246.StrAddBatch",
"0246.Stringify"
],
{
@ -2464,6 +2523,7 @@
"Integer place counter",
"KSampler (WAS)",
"KSampler Cycle",
"Latent Batch",
"Latent Input Switch",
"Latent Noise Injection",
"Latent Size to Number",
@ -2752,6 +2812,26 @@
"title_aux": "ComfyUI-AudioScheduler"
}
],
"https://github.com/abyz22/image_control": [
[
"abyz22_FirstNonNull",
"abyz22_FromBasicPipe_v2",
"abyz22_ImpactWildcardEncode",
"abyz22_ImpactWildcardEncode_GetPrompt",
"abyz22_Ksampler",
"abyz22_Padding Image",
"abyz22_SaveImage",
"abyz22_SetQueue",
"abyz22_ToBasicPipe",
"abyz22_blend_onecolor",
"abyz22_blendimages",
"abyz22_drawmask",
"abyz22_setimageinfo"
],
{
"title_aux": "image_control"
}
],
"https://github.com/adieyal/comfyui-dynamicprompts": [
[
"DPCombinatorialGenerator",
@ -2777,11 +2857,12 @@
"Aegisflow SDXL Tuple Pass",
"Aegisflow VAE Pass",
"Aegisflow controlnet preprocessor bus",
"Brightness & Contrast_Ally",
"Brightness_Contrast_Ally",
"Gaussian Blur_Ally",
"Image Flip_ally",
"Placeholder Tuple",
"aegisflow Multi_Pass"
"aegisflow Multi_Pass",
"aegisflow Multi_Pass XL"
],
{
"title_aux": "AegisFlow Utility Nodes"
@ -2806,7 +2887,7 @@
"https://github.com/alexopus/ComfyUI-Image-Saver": [
[
"Cfg Literal (Image Saver)",
"Checkpoint Selector (Image Saver)",
"Checkpoint Loader with Name (Image Saver)",
"Float Literal (Image Saver)",
"Image Saver",
"Int Literal (Image Saver)",
@ -3023,6 +3104,7 @@
"ImageBridge",
"LoadImageFromRequest",
"LoadImageWithAlpha",
"LoadValueFromRequest",
"SAM MultiLayer",
"Save Image With Workflow"
],
@ -3247,6 +3329,7 @@
"RGB to HSV",
"Rect Grab Cut",
"Remap",
"RemapFromQuadrilateral (homography)",
"RemapInsideParabolas",
"RemapInsideParabolasAdvanced",
"RemapToInnerCylinder",
@ -3415,12 +3498,42 @@
"https://github.com/chaojie/ComfyUI-DragNUWA": [
[
"DragNUWA Run",
"Load CheckPoint DragNUWA"
"Get First Image",
"Get Last Image",
"Load CheckPoint DragNUWA",
"Load Pose KeyPoints",
"Loop",
"LoopEnd_IMAGE",
"LoopStart_IMAGE",
"Split Tracking Points"
],
{
"title_aux": "ComfyUI-DragNUWA"
}
],
"https://github.com/chaojie/ComfyUI-I2VGEN-XL": [
[
"I2VGEN-XL Simple",
"Modelscope Pipeline Loader"
],
{
"title_aux": "ComfyUI-I2VGEN-XL"
}
],
"https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone": [
[
"Moore-AnimateAnyone Denoising Unet",
"Moore-AnimateAnyone Image Encoder",
"Moore-AnimateAnyone Pipeline Loader",
"Moore-AnimateAnyone Pose Guider",
"Moore-AnimateAnyone Reference Unet",
"Moore-AnimateAnyone Simple",
"Moore-AnimateAnyone VAE"
],
{
"title_aux": "ComfyUI-Moore-AnimateAnyone"
}
],
"https://github.com/chaojie/ComfyUI-MotionCtrl": [
[
"Load Motion Camera Preset",
@ -3435,6 +3548,27 @@
"title_aux": "ComfyUI-MotionCtrl"
}
],
"https://github.com/chaojie/ComfyUI-MotionCtrl-SVD": [
[
"Load Motionctrl-SVD Camera Preset",
"Load Motionctrl-SVD Checkpoint",
"Motionctrl-SVD Sample Simple"
],
{
"title_aux": "ComfyUI-MotionCtrl-SVD"
}
],
"https://github.com/chflame163/ComfyUI_LayerStyle": [
[
"LayerStyle_DropShadow",
"LayerStyle_ImageBlend",
"LayerStyle_ImageOpacity",
"LayerStyle_OuterGlow"
],
{
"title_aux": "ComfyUI Layer Style"
}
],
"https://github.com/chflame163/ComfyUI_MSSpeech_TTS": [
[
"Input Trigger",
@ -3449,7 +3583,8 @@
"https://github.com/chflame163/ComfyUI_WordCloud": [
[
"ComfyWordCloud",
"LoadTextFile"
"LoadTextFile",
"RGB_Picker"
],
{
"title_aux": "ComfyUI_WordCloud"
@ -3661,6 +3796,7 @@
"ImageCrop",
"ImageInvert",
"ImageOnlyCheckpointLoader",
"ImageOnlyCheckpointSave",
"ImagePadForOutpaint",
"ImageQuantize",
"ImageScale",
@ -3831,6 +3967,7 @@
"ExtractKeyframes+",
"GetImageSize+",
"ImageCASharpening+",
"ImageCompositeFromMaskBatch+",
"ImageCrop+",
"ImageDesaturate+",
"ImageEnhanceDifference+",
@ -3868,12 +4005,33 @@
"https://github.com/daniel-lewis-ab/ComfyUI-Llama": [
[
"Call LLM",
"Load LLM Model"
"LLM_Create_Embedding",
"LLM_Detokenize",
"LLM_Embed",
"LLM_Eval",
"LLM_Generate",
"LLM_Load_State",
"LLM_Reset",
"LLM_Sample",
"LLM_Save_State",
"LLM_Token_BOS",
"LLM_Token_EOS",
"LLM_Tokenize",
"Load LLM Model",
"Load LLM Model Advanced"
],
{
"title_aux": "ComfyUI-Llama"
}
],
"https://github.com/dave-palt/comfyui_DSP_imagehelpers": [
[
"dsp-imagehelpers-concat"
],
{
"title_aux": "comfyui_DSP_imagehelpers"
}
],
"https://github.com/dawangraoming/ComfyUI_ksampler_gpu/raw/main/ksampler_gpu.py": [
[
"KSamplerAdvancedGPU",
@ -4168,10 +4326,33 @@
],
"https://github.com/fexli/fexli-util-node-comfyui": [
[
"FEBCPrompt",
"FEBatchGenStringBCDocker",
"FEColor2Image",
"FEColorOut",
"FEDataInsertor",
"FEDataPacker",
"FEDataUnpacker",
"FEDeepClone",
"FEDictPacker",
"FEDictUnpacker",
"FEEncLoraLoader",
"FEExtraInfoAdd",
"FEGenStringBCDocker",
"FEGenStringGPT",
"FEImageNoiseGenerate",
"FEImagePadForOutpaint",
"FERandomizedColor2Image"
"FEImagePadForOutpaintByImage",
"FEOperatorIf",
"FEPythonStrOp",
"FERandomLoraSelect",
"FERandomPrompt",
"FERandomizedColor2Image",
"FERandomizedColorOut",
"FERerouteWithName",
"FESaveEncryptImage",
"FETextCombine",
"FETextInput"
],
{
"title_aux": "fexli-util-node-comfyui"
@ -4263,6 +4444,38 @@
"title_aux": "As_ComfyUI_CustomNodes"
}
],
"https://github.com/foxtrot-roger/comfyui-rf-nodes": [
[
"LogBool",
"LogFloat",
"LogInt",
"LogNumber",
"LogString",
"LogVec2",
"LogVec3",
"RF_BoolToString",
"RF_FloatToString",
"RF_IntToString",
"RF_JsonStyleLoader",
"RF_MergeLines",
"RF_NumberToString",
"RF_RangeFloat",
"RF_RangeInt",
"RF_RangeNumber",
"RF_SplitLines",
"RF_TextConcatenate",
"RF_TextInput",
"RF_TextReplace",
"RF_Timestamp",
"RF_ToString",
"RF_Vec2ToString",
"RF_Vec3ToString",
"TextLine"
],
{
"title_aux": "RF Nodes"
}
],
"https://github.com/gemell1/ComfyUI_GMIC": [
[
"GmicCliWrapper"
@ -4498,6 +4711,7 @@
"KSampler Adv. (Efficient)",
"KSampler SDXL (Eff.)",
"LatentUpscaler",
"LoRA Stack to String converter",
"LoRA Stacker",
"Manual XY Entry Info",
"NNLatentUpscale",
@ -4626,6 +4840,14 @@
"title_aux": "Knodes"
}
],
"https://github.com/kijai/ComfyUI-DDColor": [
[
"DDColor_Colorize"
],
{
"title_aux": "ComfyUI-DDColor"
}
],
"https://github.com/kijai/ComfyUI-KJNodes": [
[
"AddLabel",
@ -4781,7 +5003,15 @@
],
"https://github.com/komojini/komojini-comfyui-nodes": [
[
"FlowBuilder",
"Getter",
"ImageGetter",
"ImageMerger",
"KSamplerAdvancedCacheable",
"KSamplerCacheable",
"Setter",
"UltimateVideoLoader",
"UltimateVideoLoader (simple)",
"YouTubeVideoLoader"
],
{
@ -4860,7 +5090,9 @@
"Base64ToMask",
"ImageToBase64",
"ImageToBase64Advanced",
"LoadImageFromURL",
"LoadImageToBase64",
"LoadMaskFromURL",
"MaskImageToBase64",
"MaskToBase64",
"MaskToBase64Image",
@ -5092,7 +5324,9 @@
"InpaintPreprocessor_Provider_for_SEGS //Inspire",
"KSampler //Inspire",
"KSamplerAdvanced //Inspire",
"KSamplerAdvancedPipe //Inspire",
"KSamplerAdvancedProgress //Inspire",
"KSamplerPipe //Inspire",
"KSamplerProgress //Inspire",
"LatentBatchSplitter //Inspire",
"LeRes_DepthMap_Preprocessor_Provider_for_SEGS //Inspire",
@ -5128,6 +5362,7 @@
"RegionalSeedExplorerMask //Inspire",
"RemoveBackendData //Inspire",
"RemoveBackendDataNumberKey //Inspire",
"RemoveControlNet //Inspire",
"RetrieveBackendData //Inspire",
"RetrieveBackendDataNumberKey //Inspire",
"SeedExplorer //Inspire",
@ -5381,6 +5616,7 @@
[
"NegiTools_CompositeImages",
"NegiTools_DepthEstimationByMarigold",
"NegiTools_DetectFaceRotationForInpainting",
"NegiTools_ImageProperties",
"NegiTools_LatentProperties",
"NegiTools_NoiseImageGenerator",
@ -5415,6 +5651,15 @@
"title_aux": "comfyui-NDI"
}
],
"https://github.com/nkchocoai/ComfyUI-SizeFromPresets": [
[
"SizeFromPresetsSD15",
"SizeFromPresetsSDXL"
],
{
"title_aux": "ComfyUI-SizeFromPresets"
}
],
"https://github.com/noembryo/ComfyUI-noEmbryo": [
[
"PromptTermList1",
@ -5801,6 +6046,7 @@
"CombineMasks_",
"CombineSegMasks",
"DynamicDelayProcessor",
"EmbeddingPrompt",
"EnhanceImage",
"FaceToMask",
"FeatheredMask",
@ -5813,6 +6059,7 @@
"ImageColorTransfer",
"ImageCropByAlpha",
"IntNumber",
"JoinWithDelimiter",
"LaMaInpainting",
"LimitNumber",
"LoadImagesFromPath",
@ -5822,6 +6069,7 @@
"MultiplicationNode",
"NewLayer",
"NoiseImage",
"OutlineMask",
"PromptImage",
"PromptSimplification",
"PromptSlide",
@ -6165,6 +6413,7 @@
"GroundingDinoModelLoader (segment anything)",
"GroundingDinoSAMSegment (segment anything)",
"InvertMask (segment anything)",
"IsMaskEmpty",
"SAMModelLoader (segment anything)"
],
{
@ -6252,6 +6501,7 @@
],
"https://github.com/taabata/LCM_Inpaint-Outpaint_Comfy": [
[
"ComfyNodesToSaveCanvas",
"FloatNumber",
"FreeU_LCM",
"ImageOutputToComfyNodes",
@ -6298,7 +6548,8 @@
"https://github.com/talesofai/comfyui-browser": [
[
"LoadImageByUrl //Browser",
"SelectInputs //Browser"
"SelectInputs //Browser",
"XyzPlot //Browser"
],
{
"title_aux": "ComfyUI Browser"
@ -6395,6 +6646,7 @@
"Iterative Mixing KSampler Advanced",
"IterativeMixingSampler",
"IterativeMixingScheduler",
"IterativeMixingSchedulerAdvanced",
"Latent Batch Comparison Plot",
"Latent Batch Statistics Plot",
"MixingMaskGenerator"
@ -6726,6 +6978,8 @@
"easy XYInputs: ControlNet",
"easy XYInputs: Denoise",
"easy XYInputs: ModelMergeBlocks",
"easy XYInputs: NegativeCond",
"easy XYInputs: PositiveCond",
"easy XYInputs: PromptSR",
"easy XYInputs: Sampler/Scheduler",
"easy XYInputs: Seeds++ Batch",
@ -6747,13 +7001,14 @@
"easy imageSize",
"easy imageSizeByLongerSide",
"easy imageSizeBySide",
"easy imageToMask",
"easy kSampler",
"easy kSamplerDownscaleUnet",
"easy kSamplerInpainting",
"easy kSamplerSDTurbo",
"easy kSamplerTiled",
"easy latentCompositeMaskedWithCond",
"easy latentMultiplyBySigma",
"easy latentNoisy",
"easy loraStack",
"easy negative",
"easy pipeIn",
@ -6770,6 +7025,7 @@
"easy samLoaderPipe",
"easy seed",
"easy showSpentTime",
"easy stylesSelector",
"easy svdLoader",
"easy ultralyticsDetectorPipe",
"easy unSampler",

30
node_db/tutorial/custom-node-list.json

@ -39,6 +39,36 @@
],
"install_type": "git-clone",
"description": "This project is an `empty` custom node that is already in its own folder. It serves as a base to build any custom node. Whenever you want to create a custom node, you can download that, put it in custom_nodes, then you just have to change the names and fill it with code!"
},
{
"author": "foxtrot-roger",
"title": "comfyui-custom-nodes",
"reference": "https://github.com/foxtrot-roger/comfyui-custom-nodes",
"files": [
"https://github.com/foxtrot-roger/comfyui-custom-nodes"
],
"install_type": "git-clone",
"description": "Tutorial nodes"
},
{
"author": "GraftingRayman",
"title": "ComfyUI-Trajectory",
"reference": "https://github.com/GraftingRayman/ComfyUI-Trajectory",
"files": [
"https://github.com/GraftingRayman/ComfyUI-Trajectory"
],
"install_type": "git-clone",
"description": "Nodes:GR Trajectory"
},
{
"author": "wailovet",
"title": "ComfyUI-WW",
"reference": "https://github.com/wailovet/ComfyUI-WW",
"files": [
"https://github.com/wailovet/ComfyUI-WW"
],
"install_type": "git-clone",
"description": "Nodes:WW_ImageResize"
}
]
}

9
prestartup_script.py

@ -456,3 +456,12 @@ if os.path.exists(script_list_path):
del processed_install
del pip_list
if platform.system() == 'Windows':
try:
import asyncio
import asyncio.windows_events
asyncio.set_event_loop_policy(asyncio.windows_events.WindowsSelectorEventLoopPolicy())
print(f"[ComfyUI-Manager] Windows event loop policy mode enabled")
except Exception as e:
print(f"[ComfyUI-Manager] WARN: Windows initialization fail: {e}")
Loading…
Cancel
Save