mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2025-12-16 01:57:04 +08:00
Merge branch 'main' into manager-v4
This commit is contained in:
commit
69b6f1a66b
16
README.md
16
README.md
@ -125,7 +125,7 @@ The following settings are applied based on the section marked as `is_default`.
|
||||

|
||||
|
||||
|
||||
## cm-cli: command line tools for power user
|
||||
## cm-cli: command line tools for power users
|
||||
* A tool is provided that allows you to use the features of ComfyUI-Manager without running ComfyUI.
|
||||
* For more details, please refer to the [cm-cli documentation](docs/en/cm-cli.md).
|
||||
|
||||
@ -171,7 +171,7 @@ The following settings are applied based on the section marked as `is_default`.
|
||||
* `<current timestamp>` Ensure that the timestamp is always unique.
|
||||
* "components" should have the same structure as the content of the file stored in `<USER_DIRECTORY>/default/ComfyUI-Manager/components`.
|
||||
* `<component name>`: The name should be in the format `<prefix>::<node name>`.
|
||||
* `<compnent nodeata>`: In the nodedata of the group node.
|
||||
* `<component node data>`: In the node data 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 `<USER_DIRECTORY>/default/ComfyUI-Manager/components`.
|
||||
@ -189,7 +189,7 @@ The following settings are applied based on the section marked as `is_default`.
|
||||
* 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
|
||||
## Support for installing missing nodes
|
||||
|
||||

|
||||
|
||||
@ -229,10 +229,10 @@ The following settings are applied based on the section marked as `is_default`.
|
||||
* Logging to file feature
|
||||
* This feature is enabled by default and can be disabled by setting `file_logging = False` in the `config.ini`.
|
||||
|
||||
* Fix node(recreate): When right-clicking on a node and selecting `Fix node (recreate)`, you can recreate the node. The widget's values are reset, while the connections maintain those with the same names.
|
||||
* Fix node (recreate): When right-clicking on a node and selecting `Fix node (recreate)`, you can recreate the node. The widget's values are reset, while the connections maintain those with the same names.
|
||||
* It is used to correct errors in nodes of old workflows created before, which are incompatible with the version changes of custom nodes.
|
||||
|
||||
* Double-Click Node Title: You can set the double click behavior of nodes in the ComfyUI-Manager menu.
|
||||
* Double-Click Node Title: You can set the double-click behavior of nodes in the ComfyUI-Manager menu.
|
||||
* `Copy All Connections`, `Copy Input Connections`: Double-clicking a node copies the connections of the nearest node.
|
||||
* This action targets the nearest node within a straight-line distance of 1000 pixels from the center of the node.
|
||||
* In the case of `Copy All Connections`, it duplicates existing outputs, but since it does not allow duplicate connections, the existing output connections of the original node are disconnected.
|
||||
@ -298,7 +298,7 @@ When you run the `scan.sh` script:
|
||||
|
||||
* It updates the `github-stats.json`.
|
||||
* This uses the GitHub API, so set your token with `export GITHUB_TOKEN=your_token_here` to avoid quickly reaching the rate limit and malfunctioning.
|
||||
* To skip this step, add the `--skip-update-stat` option.
|
||||
* To skip this step, add the `--skip-stat-update` option.
|
||||
|
||||
* The `--skip-all` option applies both `--skip-update` and `--skip-stat-update`.
|
||||
|
||||
@ -306,9 +306,9 @@ When you run the `scan.sh` script:
|
||||
## Troubleshooting
|
||||
* If your `git.exe` is installed in a specific location other than system git, please install ComfyUI-Manager and run ComfyUI. Then, specify the path including the file name in `git_exe = ` in the `<USER_DIRECTORY>/default/ComfyUI-Manager/config.ini` file that is generated.
|
||||
* If updating ComfyUI-Manager itself fails, please go to the **ComfyUI-Manager** directory and execute the command `git update-ref refs/remotes/origin/main a361cc1 && git fetch --all && git pull`.
|
||||
* If you encounter the error message `Overlapped Object has pending operation at deallocation on Comfyui Manager load` under Windows
|
||||
* If you encounter the error message `Overlapped Object has pending operation at deallocation on ComfyUI Manager load` under Windows
|
||||
* Edit `config.ini` file: add `windows_selector_event_loop_policy = True`
|
||||
* if `SSL: CERTIFICATE_VERIFY_FAILED` error is occured.
|
||||
* If the `SSL: CERTIFICATE_VERIFY_FAILED` error occurs.
|
||||
* Edit `config.ini` file: add `bypass_ssl = True`
|
||||
|
||||
|
||||
|
||||
4
check.sh
4
check.sh
@ -37,7 +37,7 @@ find ~/.tmp/default -name "*.py" -print0 | xargs -0 grep -E "crypto|^_A="
|
||||
|
||||
echo
|
||||
echo CHECK3
|
||||
find ~/.tmp/default -name "requirements.txt" | xargs grep "^\s*https\\?:"
|
||||
find ~/.tmp/default -name "requirements.txt" | xargs grep "\.whl"
|
||||
find ~/.tmp/default -name "requirements.txt" | xargs grep "^\s*[^#]*https\?:"
|
||||
find ~/.tmp/default -name "requirements.txt" | xargs grep "^\s*[^#].*\.whl"
|
||||
|
||||
echo
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ This directory contains the JavaScript frontend implementation for ComfyUI-Manag
|
||||
## Sharing Components
|
||||
|
||||
- **comfyui-share-common.js**: Base functionality for workflow sharing features.
|
||||
- **comfyui-share-copus.js**: Integration with the ComfyUI Opus sharing platform.
|
||||
- **comfyui-share-copus.js**: Integration with the ComfyUI Copus sharing platform.
|
||||
- **comfyui-share-openart.js**: Integration with the OpenArt sharing platform.
|
||||
- **comfyui-share-youml.js**: Integration with the YouML sharing platform.
|
||||
|
||||
@ -47,4 +47,4 @@ CSS files are included for specific components:
|
||||
- **custom-nodes-manager.css**: Styling for the node management UI
|
||||
- **model-manager.css**: Styling for the model management UI
|
||||
|
||||
This frontend implementation provides a comprehensive yet user-friendly interface for managing the ComfyUI ecosystem.
|
||||
This frontend implementation provides a comprehensive yet user-friendly interface for managing the ComfyUI ecosystem.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
.cn-manager {
|
||||
--grid-font: -apple-system, BlinkMacSystemFont, "Segue UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
--grid-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
z-index: 1099;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
|
||||
@ -2432,6 +2432,7 @@ def update_to_stable_comfyui(repo_path):
|
||||
else:
|
||||
logging.info(f"[ComfyUI-Manager] Updating ComfyUI: {current_tag} -> {latest_tag}")
|
||||
repo.git.checkout(latest_tag)
|
||||
execute_install_script("ComfyUI", repo_path, instant_execution=False, no_deps=False)
|
||||
return 'updated', latest_tag
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
@ -2563,9 +2564,13 @@ def check_state_of_git_node_pack_single(item, do_fetch=False, do_update_check=Tr
|
||||
|
||||
|
||||
def get_installed_pip_packages():
|
||||
# extract pip package infos
|
||||
cmd = manager_util.make_pip_cmd(['freeze'])
|
||||
pips = subprocess.check_output(cmd, text=True).split('\n')
|
||||
try:
|
||||
# extract pip package infos
|
||||
cmd = manager_util.make_pip_cmd(['freeze'])
|
||||
pips = subprocess.check_output(cmd, text=True).split('\n')
|
||||
except Exception as e:
|
||||
logging.warning("[ComfyUI-Manager] Could not enumerate pip packages for snapshot: %s", e)
|
||||
return {}
|
||||
|
||||
res = {}
|
||||
for x in pips:
|
||||
|
||||
@ -5355,6 +5355,317 @@
|
||||
"filename": "LBM_relighting.safetensors",
|
||||
"url": "https://huggingface.co/jasperai/LBM_relighting/resolve/main/model.safetensors",
|
||||
"size": "5.02GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image VAE",
|
||||
"type": "VAE",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "vae/qwen-image",
|
||||
"description": "VAE model for Qwen-Image",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
||||
"filename": "qwen_image_vae.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/vae/qwen_image_vae.safetensors",
|
||||
"size": "335MB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen 2.5 VL 7B Text Encoder (fp8_scaled)",
|
||||
"type": "clip",
|
||||
"base": "Qwen-2.5-VL",
|
||||
"save_path": "text_encoders/qwen",
|
||||
"description": "Qwen 2.5 VL 7B text encoder model (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
||||
"filename": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/text_encoders/qwen_2.5_vl_7b_fp8_scaled.safetensors",
|
||||
"size": "3.75GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen 2.5 VL 7B Text Encoder",
|
||||
"type": "clip",
|
||||
"base": "Qwen-2.5-VL",
|
||||
"save_path": "text_encoders/qwen",
|
||||
"description": "Qwen 2.5 VL 7B text encoder model",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
||||
"filename": "qwen_2.5_vl_7b.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/text_encoders/qwen_2.5_vl_7b.safetensors",
|
||||
"size": "7.51GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image Diffusion Model (fp8_e4m3fn)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "diffusion_models/qwen-image",
|
||||
"description": "Qwen-Image diffusion model (fp8_e4m3fn)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
||||
"filename": "qwen_image_fp8_e4m3fn.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_fp8_e4m3fn.safetensors",
|
||||
"size": "4.89GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image Diffusion Model (bf16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "diffusion_models/qwen-image",
|
||||
"description": "Qwen-Image diffusion model (bf16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
||||
"filename": "qwen_image_bf16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_bf16.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit 2509 Diffusion Model (fp8_e4m3fn)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "diffusion_models/qwen-image-edit",
|
||||
"description": "Qwen-Image-Edit 2509 diffusion model (fp8_e4m3fn)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
||||
"filename": "qwen_image_edit_2509_fp8_e4m3fn.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_2509_fp8_e4m3fn.safetensors",
|
||||
"size": "4.89GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Qwen-Image-Edit 2509 Diffusion Model (bf16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "diffusion_models/qwen-image-edit",
|
||||
"description": "Qwen-Image-Edit 2509 diffusion model (bf16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
||||
"filename": "qwen_image_edit_2509_bf16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_2509_bf16.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Qwen-Image-Edit Diffusion Model (fp8_e4m3fn)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "diffusion_models/qwen-image-edit",
|
||||
"description": "Qwen-Image-Edit diffusion model (fp8_e4m3fn)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
||||
"filename": "qwen_image_edit_fp8_e4m3fn.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_fp8_e4m3fn.safetensors",
|
||||
"size": "4.89GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Qwen-Image-Edit Diffusion Model (bf16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "diffusion_models/qwen-image-edit",
|
||||
"description": "Qwen-Image-Edit diffusion model (bf16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
||||
"filename": "qwen_image_edit_bf16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_bf16.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 8steps V1.0",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 8-step LoRA model V1.0",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-8steps-V1.0.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V1.0.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 4steps V1.0",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 4-step LoRA model V1.0",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-4steps-V1.0.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V1.0.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 4steps V1.0 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 4-step LoRA model V1.0 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-4steps-V1.0-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V1.0-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 4steps V2.0",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 4-step LoRA model V2.0",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-4steps-V2.0.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V2.0.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 4steps V2.0 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 4-step LoRA model V2.0 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-4steps-V2.0-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V2.0-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 8steps V1.1",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 8-step LoRA model V1.1",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-8steps-V1.1.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V1.1.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 8steps V1.1 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 8-step LoRA model V1.1 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-8steps-V1.1-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V1.1-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 8steps V2.0",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 8-step LoRA model V2.0",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-8steps-V2.0.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V2.0.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Lightning 8steps V2.0 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "loras/qwen-image-lightning",
|
||||
"description": "Qwen-Image-Lightning 8-step LoRA model V2.0 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Lightning-8steps-V2.0-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V2.0-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-Lightning 4steps V1.0",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-Lightning 4-step LoRA model V1.0",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-Lightning-4steps-V1.0.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-4steps-V1.0.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-Lightning 4steps V1.0 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-Lightning 4-step LoRA model V1.0 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-Lightning-4steps-V1.0-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-4steps-V1.0-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-Lightning 8steps V1.0",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-Lightning 8-step LoRA model V1.0",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-Lightning-8steps-V1.0.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-8steps-V1.0.safetensors",
|
||||
"size": "9.78GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-Lightning 8steps V1.0 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-Lightning 8-step LoRA model V1.0 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-Lightning-8steps-V1.0-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-8steps-V1.0-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-2509-Lightning 4steps V1.0 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-2509-Lightning 4-step LoRA model V1.0 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-2509-Lightning-4steps-V1.0-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-4steps-V1.0-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-2509-Lightning 4steps V1.0 (fp32)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-2509-Lightning 4-step LoRA model V1.0 (fp32)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-2509-Lightning-4steps-V1.0-fp32.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-4steps-V1.0-fp32.safetensors",
|
||||
"size": "39.1GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-2509-Lightning 8steps V1.0 (bf16)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-2509-Lightning 8-step LoRA model V1.0 (bf16)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-2509-Lightning-8steps-V1.0-bf16.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-8steps-V1.0-bf16.safetensors",
|
||||
"size": "19.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image-Edit-2509-Lightning 8steps V1.0 (fp32)",
|
||||
"type": "lora",
|
||||
"base": "Qwen-Image-Edit",
|
||||
"save_path": "loras/qwen-image-edit-lightning",
|
||||
"description": "Qwen-Image-Edit-2509-Lightning 8-step LoRA model V1.0 (fp32)",
|
||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
||||
"filename": "Qwen-Image-Edit-2509-Lightning-8steps-V1.0-fp32.safetensors",
|
||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-8steps-V1.0-fp32.safetensors",
|
||||
"size": "39.1GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image InstantX ControlNet Union",
|
||||
"type": "controlnet",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "controlnet/qwen-image/instantx",
|
||||
"description": "Qwen-Image InstantX ControlNet Union model",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets",
|
||||
"filename": "Qwen-Image-InstantX-ControlNet-Union.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets/resolve/main/split_files/controlnet/Qwen-Image-InstantX-ControlNet-Union.safetensors",
|
||||
"size": "2.54GB"
|
||||
},
|
||||
{
|
||||
"name": "Qwen-Image InstantX ControlNet Inpainting",
|
||||
"type": "controlnet",
|
||||
"base": "Qwen-Image",
|
||||
"save_path": "controlnet/qwen-image/instantx",
|
||||
"description": "Qwen-Image InstantX ControlNet Inpainting model",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets",
|
||||
"filename": "Qwen-Image-InstantX-ControlNet-Inpainting.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets/resolve/main/split_files/controlnet/Qwen-Image-InstantX-ControlNet-Inpainting.safetensors",
|
||||
"size": "2.54GB"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -139,9 +139,9 @@ You can set whether to use ComfyUI-Manager solely via CLI.
|
||||
`restore-dependencies`
|
||||
|
||||
* This command can be used if custom nodes are installed under the `ComfyUI/custom_nodes` path but their dependencies are not installed.
|
||||
* It is useful when starting a new cloud instance, like colab, where dependencies need to be reinstalled and installation scripts re-executed.
|
||||
* It is useful when starting a new cloud instance, like Colab, where dependencies need to be reinstalled and installation scripts re-executed.
|
||||
* It can also be utilized if ComfyUI is reinstalled and only the custom_nodes path has been backed up and restored.
|
||||
|
||||
### 7. Clear
|
||||
|
||||
In the GUI, installations, updates, or snapshot restorations are scheduled to execute the next time ComfyUI is launched. The `clear` command clears this scheduled state, ensuring no pre-execution actions are applied.
|
||||
In the GUI, installations, updates, or snapshot restorations are scheduled to execute the next time ComfyUI is launched. The `clear` command clears this scheduled state, ensuring no pre-execution actions are applied.
|
||||
|
||||
@ -23,13 +23,13 @@ OPTIONS:
|
||||
## How To Use?
|
||||
* `python cm-cli.py` 를 통해서 실행 시킬 수 있습니다.
|
||||
* 예를 들어 custom node를 모두 업데이트 하고 싶다면
|
||||
* ComfyUI-Manager경로 에서 `python cm-cli.py update all` 를 command를 실행할 수 있습니다.
|
||||
* ComfyUI-Manager 경로에서 `python cm-cli.py update all` 명령을 실행할 수 있습니다.
|
||||
* ComfyUI 경로에서 실행한다면, `python custom_nodes/ComfyUI-Manager/cm-cli.py update all` 와 같이 cm-cli.py 의 경로를 지정할 수도 있습니다.
|
||||
|
||||
## Prerequisite
|
||||
* ComfyUI 를 실행하는 python과 동일한 python 환경에서 실행해야 합니다.
|
||||
* venv를 사용할 경우 해당 venv를 activate 한 상태에서 실행해야 합니다.
|
||||
* portable 버전을 사용할 경우 run_nvidia_gpu.bat 파일이 있는 경로인 경우, 다음과 같은 방식으로 코맨드를 실행해야 합니다.
|
||||
* portable 버전을 사용할 경우 run_nvidia_gpu.bat 파일이 있는 경로인 경우, 다음과 같은 방식으로 명령을 실행해야 합니다.
|
||||
`.\python_embeded\python.exe ComfyUI\custom_nodes\ComfyUI-Manager\cm-cli.py update all`
|
||||
* ComfyUI 의 경로는 COMFYUI_PATH 환경 변수로 설정할 수 있습니다. 만약 생략할 경우 다음과 같은 경고 메시지가 나타나며, ComfyUI-Manager가 설치된 경로를 기준으로 상대 경로로 설정됩니다.
|
||||
```
|
||||
@ -40,8 +40,8 @@ OPTIONS:
|
||||
|
||||
### 1. --channel, --mode
|
||||
* 정보 보기 기능과 커스텀 노드 관리 기능의 경우는 --channel과 --mode를 통해 정보 DB를 설정할 수 있습니다.
|
||||
* 예들 들어 `python cm-cli.py update all --channel recent --mode remote`와 같은 command를 실행할 경우, 현재 ComfyUI-Manager repo에 내장된 로컬의 정보가 아닌 remote의 최신 정보를 기준으로 동작하며, recent channel에 있는 목록을 대상으로만 동작합니다.
|
||||
* --channel, --mode 는 `simple-show, show, install, uninstall, update, disable, enable, fix` command에서만 사용 가능합니다.
|
||||
* 예를 들어 `python cm-cli.py update all --channel recent --mode remote`와 같은 명령을 실행할 경우, 현재 ComfyUI-Manager repo에 내장된 로컬의 정보가 아닌 remote의 최신 정보를 기준으로 동작하며, recent channel에 있는 목록을 대상으로만 동작합니다.
|
||||
* --channel, --mode 는 `simple-show, show, install, uninstall, update, disable, enable, fix` 명령에서만 사용 가능합니다.
|
||||
|
||||
### 2. 관리 정보 보기
|
||||
|
||||
@ -51,7 +51,7 @@ OPTIONS:
|
||||
* `[show|simple-show]` - `show`는 상세하게 정보를 보여주며, `simple-show`는 간단하게 정보를 보여줍니다.
|
||||
|
||||
|
||||
`python cm-cli.py show installed` 와 같은 코맨드를 실행하면 설치된 커스텀 노드의 정보를 상세하게 보여줍니다.
|
||||
`python cm-cli.py show installed` 와 같은 명령을 실행하면 설치된 커스텀 노드의 정보를 상세하게 보여줍니다.
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
|
||||
@ -67,7 +67,7 @@ FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main
|
||||
[ DISABLED ] ComfyUI-Loopchain (author: Fannovel16)
|
||||
```
|
||||
|
||||
`python cm-cli.py simple-show installed` 와 같은 코맨드를 이용해서 설치된 커스텀 노드의 정보를 간단하게 보여줍니다.
|
||||
`python cm-cli.py simple-show installed` 와 같은 명령을 이용해서 설치된 커스텀 노드의 정보를 간단하게 보여줍니다.
|
||||
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
@ -89,7 +89,7 @@ ComfyUI-Loopchain
|
||||
* `installed`: enable, disable 여부와 상관없이 설치된 모든 노드를 보여줍니다
|
||||
* `not-installed`: 설치되지 않은 커스텀 노드의 목록을 보여줍니다.
|
||||
* `all`: 모든 커스텀 노드의 목록을 보여줍니다.
|
||||
* `snapshot`: 현재 설치된 커스텀 노드의 snapshot 정보를 보여줍니다. `show`롤 통해서 볼 경우는 json 출력 형태로 보여주며, `simple-show`를 통해서 볼 경우는 간단하게, 커밋 해시와 함께 보여줍니다.
|
||||
* `snapshot`: 현재 설치된 커스텀 노드의 snapshot 정보를 보여줍니다. `show`를 통해서 볼 경우는 json 출력 형태로 보여주며, `simple-show`를 통해서 볼 경우는 간단하게, 커밋 해시와 함께 보여줍니다.
|
||||
* `snapshot-list`: ComfyUI-Manager/snapshots 에 저장된 snapshot 파일의 목록을 보여줍니다.
|
||||
|
||||
### 3. 커스텀 노드 관리 하기
|
||||
@ -98,7 +98,7 @@ ComfyUI-Loopchain
|
||||
|
||||
* `python cm-cli.py install ComfyUI-Impact-Pack ComfyUI-Inspire-Pack ComfyUI_experiments` 와 같이 커스텀 노드의 이름을 나열해서 관리 기능을 적용할 수 있습니다.
|
||||
* 커스텀 노드의 이름은 `show`를 했을 때 보여주는 이름이며, git repository의 이름입니다.
|
||||
(추후 nickname 을 사용가능하돌고 업데이트 할 예정입니다.)
|
||||
(추후 nickname을 사용 가능하도록 업데이트할 예정입니다.)
|
||||
|
||||
`[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||
|
||||
@ -124,7 +124,7 @@ ComfyUI-Loopchain
|
||||
* `--pip-non-local-url`: web URL에 등록된 pip 패키지들에 대해서 복구를 수행
|
||||
* `--pip-local-url`: local 경로를 지정하고 있는 pip 패키지들에 대해서 복구를 수행
|
||||
* `--user-directory`: 사용자 디렉토리 설정
|
||||
* `--restore-to`: 복구될 커스텀 노드가 설치될 경로. (이 옵션을 적용할 경우 오직 대상 경로에 설치된 custom nodes 만 설치된 것으로 인식함.)
|
||||
* `--restore-to`: 복구될 커스텀 노드가 설치될 경로. (이 옵션을 적용할 경우 오직 대상 경로에 설치된 custom nodes만 설치된 것으로 인식함.)
|
||||
|
||||
### 5. CLI only mode
|
||||
|
||||
@ -133,7 +133,7 @@ ComfyUI-Manager를 CLI로만 사용할 것인지를 설정할 수 있습니다.
|
||||
`cli-only-mode [enable|disable]`
|
||||
|
||||
* security 혹은 policy 의 이유로 GUI 를 통한 ComfyUI-Manager 사용을 제한하고 싶은 경우 이 모드를 사용할 수 있습니다.
|
||||
* CLI only mode를 적용할 경우 ComfyUI-Manager 가 매우 제한된 상태로 로드되어, 내부적으로 제공하는 web API가 비활성화 되며, 메인 메뉴에서도 Manager 버튼이 표시되지 않습니다.
|
||||
* CLI only mode를 적용할 경우 ComfyUI-Manager 가 매우 제한된 상태로 로드되어, 내부적으로 제공하는 web API가 비활성화되며, 메인 메뉴에서도 Manager 버튼이 표시되지 않습니다.
|
||||
|
||||
|
||||
### 6. 의존성 설치
|
||||
@ -141,10 +141,10 @@ ComfyUI-Manager를 CLI로만 사용할 것인지를 설정할 수 있습니다.
|
||||
`restore-dependencies`
|
||||
|
||||
* `ComfyUI/custom_nodes` 하위 경로에 커스텀 노드들이 설치되어 있긴 하지만, 의존성이 설치되지 않은 경우 사용할 수 있습니다.
|
||||
* colab 과 같이 cloud instance를 새로 시작하는 경우 의존성 재설치 및 설치 스크립트가 재실행 되어야 하는 경우 사용합니다.
|
||||
* ComfyUI을 재설치할 경우, custom_nodes 경로만 백업했다가 재설치 할 경우 활용 가능합니다.
|
||||
* Colab과 같이 cloud instance를 새로 시작하는 경우 의존성 재설치 및 설치 스크립트가 재실행되어야 하는 경우 사용합니다.
|
||||
* ComfyUI를 재설치할 경우, custom_nodes 경로만 백업했다가 재설치할 경우 활용 가능합니다.
|
||||
|
||||
|
||||
### 7. clear
|
||||
|
||||
GUI에서 install, update를 하거나 snapshot 을 restore하는 경우 예약을 통해서 다음번 ComfyUI를 실행할 경우 실행되는 구조입니다. `clear` 는 이런 예약 상태를 clear해서, 아무런 사전 실행이 적용되지 않도록 합니다.
|
||||
GUI에서 install, update를 하거나 snapshot을 restore하는 경우 예약을 통해서 다음번 ComfyUI를 실행할 경우 실행되는 구조입니다. `clear` 는 이런 예약 상태를 clear해서, 아무런 사전 실행이 적용되지 않도록 합니다.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -169,6 +169,16 @@
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A fork of KJNodes for ComfyUI.\nVarious quality of life -nodes for ComfyUI, mostly just visual stuff to improve usability"
|
||||
},
|
||||
{
|
||||
"author": "huixingyun",
|
||||
"title": "ComfyUI-SoundFlow",
|
||||
"reference": "https://github.com/huixingyun/ComfyUI-SoundFlow",
|
||||
"files": [
|
||||
"https://github.com/huixingyun/ComfyUI-SoundFlow"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "forked from https://github.com/fredconex/ComfyUI-SoundFlow (removed)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,5 +1,690 @@
|
||||
{
|
||||
"custom_nodes": [
|
||||
{
|
||||
"author": "cedarconnor",
|
||||
"title": "ComfyUI-GEN3C-Gsplat [REMOVED]",
|
||||
"reference": "https://github.com/cedarconnor/ComfyUI-GEN3C-Gsplat",
|
||||
"files": [
|
||||
"https://github.com/cedarconnor/ComfyUI-GEN3C-Gsplat"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom ComfyUI node pack that bridges Cosmos/GEN3C video generation with in-graph Gaussian Splat (3DGS) training. It adds camera/trajectory tooling, dataset exporters, and two training backends (Nerfstudio CLI wrapper and an in-process gsplat optimizer) so artists can go from prompt to splat entirely inside ComfyUI.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "dowa-git",
|
||||
"title": "comfyui-dowa [REMOVED]",
|
||||
"reference": "https://github.com/dowa-git/comfyui-dowa",
|
||||
"files": [
|
||||
"https://github.com/dowa-git/comfyui-dowa"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Professional navigation bar widget for ComfyUI with JWT-based user authentication, workflow templates, and team collaboration features in a purple gradient design."
|
||||
},
|
||||
{
|
||||
"author": "Fablestarexpanse",
|
||||
"title": "Timer-Node-Comfyui [REMOVED]",
|
||||
"reference": "https://github.com/Fablestarexpanse/Timer-Node-Comfyui",
|
||||
"files": [
|
||||
"https://github.com/Fablestarexpanse/Timer-Node-Comfyui"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom ComfyUI node that displays live processing time in a red digital countdown clock format, perfect for monitoring image generation times and tracking performance between workflow nodes."
|
||||
},
|
||||
{
|
||||
"author": "cedarconnor",
|
||||
"title": "ComfyUI-OmniX [REMOVED]",
|
||||
"reference": "https://github.com/cedarconnor/ComfyUI-OmniX",
|
||||
"files": [
|
||||
"https://github.com/cedarconnor/ComfyUI-OmniX"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Extract comprehensive scene properties from 360-degree equirectangular panoramas, including depth, normals, and PBR materials, using OmniX adapters with Flux."
|
||||
},
|
||||
{
|
||||
"author": "cedarconnor",
|
||||
"title": "ComfyUI-DiT360 [REMOVED]",
|
||||
"reference": "https://github.com/cedarconnor/ComfyUI-DiT360",
|
||||
"files": [
|
||||
"https://github.com/cedarconnor/ComfyUI-DiT360"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Generate high-fidelity 360-degree panoramic images using the DiT360 diffusion transformer model in ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "PozzettiAndrea",
|
||||
"title": "ComfyUI-AnyTop [REMOVED]",
|
||||
"reference": "https://github.com/PozzettiAndrea/ComfyUI-AnyTop",
|
||||
"files": [
|
||||
"https://github.com/PozzettiAndrea/ComfyUI-AnyTop"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Standalone ComfyUI custom nodes for AnyTop - Universal Motion Generation for Any Skeleton Topology."
|
||||
},
|
||||
{
|
||||
"author": "penposs",
|
||||
"title": "ComfyUI-Banana-Node [REMOVED]",
|
||||
"reference": "https://github.com/penposs/ComfyUI-Banana-Node",
|
||||
"files": [
|
||||
"https://github.com/penposs/ComfyUI-Banana-Node"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node for ComfyUI that generates images using Google’s Gemini 2.5 Flash Image Preview API."
|
||||
},
|
||||
{
|
||||
"author": "spiralmountain",
|
||||
"title": "ComfyUI_HDNodes [REMOVED]",
|
||||
"reference": "https://github.com/spiralmountain/ComfyUI_HDNodes",
|
||||
"files": [
|
||||
"https://github.com/spiralmountain/ComfyUI_HDNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes for ComfyUI that enable video generation using ByteDance's Seedance model via [a/Fal.ai](https://fal.ai/)."
|
||||
},
|
||||
{
|
||||
"author": "fredconex",
|
||||
"title": "Sync Edit [REMOVED]",
|
||||
"reference": "https://github.com/fredconex/ComfyUI-SyncEdit",
|
||||
"files": [
|
||||
"https://github.com/fredconex/ComfyUI-SyncEdit"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This node allow to intercept changes on the input string and choose between use the current one or sync with incoming new one."
|
||||
},
|
||||
{
|
||||
"author": "fredconex",
|
||||
"title": "ComfyUI-SoundFlow [REMOVED]",
|
||||
"reference": "https://github.com/fredconex/ComfyUI-SoundFlow",
|
||||
"files": [
|
||||
"https://github.com/fredconex/ComfyUI-SoundFlow"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This is a bunch of nodes for ComfyUI to help with sound work."
|
||||
},
|
||||
{
|
||||
"author": "fredconex",
|
||||
"title": "SongBloom [REMOVED]",
|
||||
"reference": "https://github.com/fredconex/ComfyUI-SongBloom",
|
||||
"files": [
|
||||
"https://github.com/fredconex/ComfyUI-SongBloom"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI Nodes for SongBloom"
|
||||
},
|
||||
{
|
||||
"author": "EQXai",
|
||||
"title": "ComfyUI_EQX [REMOVED]",
|
||||
"reference": "https://github.com/EQXai/ComfyUI_EQX",
|
||||
"files": [
|
||||
"https://github.com/EQXai/ComfyUI_EQX"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: SaveImage_EQX, File Image Selector, Load Prompt From File - EQX, LoraStackEQX_random, Extract Filename - EQX, Extract LORA name - EQX, NSFW Detector EQX, NSFW Detector Advanced EQX"
|
||||
},
|
||||
{
|
||||
"author": "wizdroid",
|
||||
"title": "Wizdroid ComfyUI Outfit Selection [REMOVED]",
|
||||
"reference": "https://github.com/wizdroid/wizdroid-fashionista",
|
||||
"files": [
|
||||
"https://github.com/wizdroid/wizdroid-fashionista"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A comprehensive outfit generation system for ComfyUI with AI-powered prompt enhancement and dynamic outfit composition."
|
||||
},
|
||||
{
|
||||
"author": "enternalsaga",
|
||||
"title": "NBA-ComfyUINode [REMOVED]",
|
||||
"reference": "https://github.com/enternalsaga/NBA-ComfyUINode-public",
|
||||
"files": [
|
||||
"https://github.com/enternalsaga/NBA-ComfyUINode-public"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Version 1.2.1 - Dependency cleanup and archived LineSelector node\nA comprehensive collection of custom nodes for ComfyUI, providing advanced image processing, workflow control, and utility functions to enhance your AI image generation workflows."
|
||||
},
|
||||
{
|
||||
"author": "sselpah",
|
||||
"title": "ComfyUI-sselpah-nodes [REMOVED]",
|
||||
"reference": "https://github.com/sselpah/ComfyUI-sselpah-nodes",
|
||||
"files": [
|
||||
"https://github.com/sselpah/ComfyUI-sselpah-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Extension of IPAdapter implementation by cubiq and whoever contributed to that repository"
|
||||
},
|
||||
{
|
||||
"author": "vsaan212",
|
||||
"title": "ComfyUI Text Split Node [REMOVED]",
|
||||
"reference": "https://github.com/vsaan212/Comfy-ui-textsplit",
|
||||
"files": [
|
||||
"https://github.com/vsaan212/Comfy-ui-textsplit"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom ComfyUI node that splits text into multiple outputs for feeding complex multi-scene renders. This node allows you to dynamically control the number of splits and use custom separators."
|
||||
},
|
||||
{
|
||||
"author": "EnragedAntelope",
|
||||
"title": "ComfyUI-Doubutsu-Describer [DEPRECATED]",
|
||||
"reference": "https://github.com/EnragedAntelope/ComfyUI-Doubutsu-Describer",
|
||||
"files": [
|
||||
"https://github.com/EnragedAntelope/ComfyUI-Doubutsu-Describer"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This custom node for ComfyUI allows you to use the Doubutsu small VLM model to describe images. Credit and further information on Doubutsu: [a/https://huggingface.co/qresearch/doubutsu-2b-pt-756](https://huggingface.co/qresearch/doubutsu-2b-pt-756)"
|
||||
},
|
||||
{
|
||||
"author": "vsaan212",
|
||||
"title": "ComfyUI Subject Selector [DEPRECATED]",
|
||||
"reference": "https://github.com/vsaan212/ComfyUI_subjectselector",
|
||||
"files": [
|
||||
"https://github.com/vsaan212/ComfyUI_subjectselector"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI_subjectselector is a custom ComfyUI node that allows you to manage and select text-based subject descriptions directly from the workflow UI. This node was designed to pair seamlessly with [a/ComfyUI-textsplit](https://github.com/vsaan212/Comfy-ui-textsplit), providing a clean, modular way to feed descriptive text prompts into your generation pipeline."
|
||||
},
|
||||
{
|
||||
"author": "agxagi",
|
||||
"title": "Autoregressive Transformer and Rolling Diffusion Sampler for ComfyUI [REMOVED]",
|
||||
"reference": "https://github.com/agxagi/ComfyUI-GPT4o-Image-Gen-FLUX-DEV",
|
||||
"files": [
|
||||
"https://github.com/agxagi/ComfyUI-GPT4o-Image-Gen-FLUX-DEV"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom ComfyUI node that implements an Autoregressive Transformer and Rolling Diffusion-like Decoder using Black Forest Lab's Flux-Dev model for accurate text-to-image generation, similar to GPT-4o's image generation approach.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "walke2019",
|
||||
"title": "ComfyUI-GGUF-VisionLM [REMOVED]",
|
||||
"reference": "https://github.com/walke2019/ComfyUI-GGUF-VisionLM",
|
||||
"files": [
|
||||
"https://github.com/walke2019/ComfyUI-GGUF-VisionLM"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI nodes for running GGUF quantized Qwen2.5-VL models using llama.cpp"
|
||||
},
|
||||
{
|
||||
"author": "neocrz",
|
||||
"title": "comfyui-tinyae [REMOVED]",
|
||||
"reference": "https://github.com/neocrz/comfyui-tinyae",
|
||||
"files": [
|
||||
"https://github.com/neocrz/comfyui-tinyae"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: TinyAE Encode (Image/Video), TinyAE Decode (Image/Video), TinyAE Encode Tiled (Image), TinyAE Decode Tiled (Image)"
|
||||
},
|
||||
{
|
||||
"author": "Laser-one",
|
||||
"title": "ComfyUI-align-pose [REMOVED]",
|
||||
"reference": "https://github.com/Laser-one/ComfyUI-align-pose",
|
||||
"files": [
|
||||
"https://github.com/Laser-one/ComfyUI-align-pose"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES:align pose"
|
||||
},
|
||||
{
|
||||
"author": "nomadoor",
|
||||
"title": "ComfyUI Video Stabilizer",
|
||||
"reference": "https://github.com/nomadoor/ComfyUI-Video-Stabilizer",
|
||||
"files": [
|
||||
"https://github.com/nomadoor/ComfyUI-Video-Stabilizer"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Two complementary stabiliser nodes for ComfyUI: Video Stabilizer (Classic), Video Stabilizer (Flow)"
|
||||
},
|
||||
{
|
||||
"author": "0xhappydev",
|
||||
"title": "comfyui-qwen-image-tools",
|
||||
"reference": "https://github.com/0xhappydev/comfyui-qwen-image-tools",
|
||||
"files": [
|
||||
"https://github.com/0xhappydev/comfyui-qwen-image-tools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes for Qwen-Image-Edit with multi-image support, more flexibility around the vision transformer (qwen2.5-vl), custom system prompts, and some other experimental things to come."
|
||||
},
|
||||
{
|
||||
"author": "Rathius-Saranoth",
|
||||
"title": "Rathius ComfyUI Nodes",
|
||||
"reference": "https://github.com/Rathius-Saranoth/rathius-comfyui-nodes",
|
||||
"files": [
|
||||
"https://github.com/Rathius-Saranoth/rathius-comfyui-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes for ComfyUI by Rathius"
|
||||
},
|
||||
{
|
||||
"author": "Hiero207",
|
||||
"title": "Hiero-Nodes [REMOVED]",
|
||||
"id": "hiero",
|
||||
"reference": "https://github.com/Hiero207/ComfyUI-Hiero-Nodes",
|
||||
"files": [
|
||||
"https://github.com/Hiero207/ComfyUI-Hiero-Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Post to Discord w/ Webhook"
|
||||
},
|
||||
{
|
||||
"author": "NeoDroleDeGueule",
|
||||
"title": "comfyui-image-mixer",
|
||||
"reference": "https://github.com/NeoDroleDeGueule/comfyui-image-mixer [REMOVED]",
|
||||
"files": [
|
||||
"https://github.com/NeoDroleDeGueule/comfyui-image-mixer"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A ComfyUI custom node that blends two images in latent space using a mix factor slider."
|
||||
},
|
||||
{
|
||||
"author": "Glarus-akash",
|
||||
"title": "ComfyUI_Image_Upscaler [REMOVED]",
|
||||
"reference": "https://github.com/Glarus-akash/ComfyUI_Image_Upscaler",
|
||||
"files": [
|
||||
"https://github.com/Glarus-akash/ComfyUI_Image_Upscaler"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Welcome to the Image Upscaler & Restorer project! This tool utilizes the [a/GFPGAN](https://github.com/TencentARC/GFPGAN) algorithm to enhance and restore images, providing a seamless way to improve image quality."
|
||||
},
|
||||
{
|
||||
"author": "styletransfer",
|
||||
"title": "Sequential Group Controller for ComfyUI [REMOVED]",
|
||||
"reference": "https://github.com/styletransfer/ComfyUI_SequentialGroupController",
|
||||
"files": [
|
||||
"https://github.com/styletransfer/ComfyUI_SequentialGroupController"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Control which groups execute based on iteration ranges - a simplified alternative to complex conditional branching workflows."
|
||||
},
|
||||
{
|
||||
"author": "xl0",
|
||||
"title": "q_tools [REMOVED]",
|
||||
"reference": "https://github.com/xl0/q_tools",
|
||||
"files": [
|
||||
"https://github.com/xl0/q_tools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: QLoadLatent, QLinearScheduler, QPreviewLatent, QGaussianLatent, QUniformLatent, QKSampler"
|
||||
},
|
||||
{
|
||||
"author": "tmode-1960",
|
||||
"title": "comfyui-ta-nodes-pack [REMOVED]",
|
||||
"reference": "https://github.com/tmode-1960/comfyui-ta-nodes-pack",
|
||||
"files": [
|
||||
"https://github.com/tmode-1960/comfyui-ta-nodes-pack"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Model loaders with an additional model name output"
|
||||
},
|
||||
{
|
||||
"author": "Shadetail",
|
||||
"title": "Eagleshadow Custom Nodes [REMOVED]",
|
||||
"id": "eagleshadow",
|
||||
"reference": "https://github.com/Shadetail/ComfyUI_Eagleshadow",
|
||||
"files": [
|
||||
"https://github.com/Shadetail/ComfyUI_Eagleshadow"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes for ComfyUI by Eagleshadow."
|
||||
},
|
||||
{
|
||||
"author": "manycore-maas",
|
||||
"title": "ComfyUI-SpatialGen [REMOVED]",
|
||||
"reference": "https://github.com/manycore-maas/ComfyUI-SpatialGen",
|
||||
"files": [
|
||||
"https://github.com/manycore-maas/ComfyUI-SpatialGen"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Scene Viewer of SpatialGen"
|
||||
},
|
||||
{
|
||||
"author": "YinBailiang",
|
||||
"title": "MergeBlockWeighted_fo_ComfyUI [REMOVED]",
|
||||
"id": "mergeblockweighted_fo_comfyui",
|
||||
"reference": "https://github.com/YinBailiang/MergeBlockWeighted_fo_ComfyUI",
|
||||
"files": [
|
||||
"https://github.com/YinBailiang/MergeBlockWeighted_fo_ComfyUI"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes: MergeBlockWeighted"
|
||||
},
|
||||
{
|
||||
"author": "facok",
|
||||
"title": "ComfyUI-FokToolset [REMOVED]",
|
||||
"reference": "https://github.com/facok/ComfyUI-FokToolset",
|
||||
"files": [
|
||||
"https://github.com/facok/ComfyUI-FokToolset"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Fok Preprocess Ref Image (Phantom)"
|
||||
},
|
||||
{
|
||||
"author": "Elawphant",
|
||||
"title": "ComfyUI-MusicGen [WIP]",
|
||||
"id": "musicgen",
|
||||
"reference": "https://github.com/Elawphant/ComfyUI-MusicGen",
|
||||
"files": [
|
||||
"https://github.com/Elawphant/ComfyUI-MusicGen"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI for Meta MusicGen."
|
||||
},
|
||||
{
|
||||
"author": "isaac-mcfadyen",
|
||||
"title": "ComfyUI-QwenClip [REMOVED]",
|
||||
"reference": "https://github.com/isaac-mcfadyen/ComfyUI-QwenClip",
|
||||
"files": [
|
||||
"https://github.com/isaac-mcfadyen/ComfyUI-QwenClip"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A variety of random text encoder tools intended for use with ComfyUI and Qwen Image/Qwen Image Edit. More (may) be added as I try out various modifications to Qwen Image."
|
||||
},
|
||||
{
|
||||
"author": "Gaotian",
|
||||
"title": "KLComfyUI-Nodes [REMOVED]",
|
||||
"reference": "https://github.com/Gaotian-cpu/KLComfyUI-Nodes",
|
||||
"files": [
|
||||
"https://github.com/Gaotian-cpu/KLComfyUI-Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Single Video_Img Callback"
|
||||
},
|
||||
{
|
||||
"author": "geltz",
|
||||
"title": "Momentum Guidance for ComfyUI [REMOVED]",
|
||||
"reference": "https://github.com/geltz/ComfyUI-MomentumGuidance",
|
||||
"files": [
|
||||
"https://github.com/geltz/ComfyUI-MomentumGuidance"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Momentum Guidance (MG) is a training-free guidance method that reduces computational cost by 40% compared to standard guidance techniques like CFG or PAG."
|
||||
},
|
||||
{
|
||||
"author": "GeekyGhost",
|
||||
"title": "Studio42 Image, Audio, and Video Editing Suite for ComfyUI [REMOVED]",
|
||||
"reference": "https://github.com/GeekyGhost/24oiduts-ComfyUI",
|
||||
"files": [
|
||||
"https://github.com/GeekyGhost/24oiduts-ComfyUI"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Studio42 is a comprehensive suite of advanced custom nodes that brings professional-grade image and video editing capabilities to ComfyUI. Designed for efficiency, quality, and creative flexibility, this suite provides cutting-edge background removal, layer composition, and patch manipulation tools used in modern VFX and content creation workflows."
|
||||
},
|
||||
{
|
||||
"author": "rvage",
|
||||
"title": "ComfyUI-RvTools-X [REMOVED]",
|
||||
"reference": "https://github.com/r-vage/ComfyUI-RvTools-X",
|
||||
"files": [
|
||||
"https://github.com/r-vage/ComfyUI-RvTools-X"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI custom nodes and utilities for workflow building, type conversions, checkpoint/pipe loaders and file utilities."
|
||||
},
|
||||
{
|
||||
"author": "heyburns",
|
||||
"title": "LinxUtil [REMOVED]",
|
||||
"reference": "https://github.com/heyburns/LinxUtil",
|
||||
"files": [
|
||||
"https://github.com/heyburns/LinxUtil"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Utility nodes for ComfyUI. Created solely for my own use case, shared as a courtesy only.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "fcanfora",
|
||||
"title": "comfyui-camera-tools [REMOVED]",
|
||||
"reference": "https://github.com/fcanfora/comfyui-camera-tools",
|
||||
"files": [
|
||||
"https://github.com/fcanfora/comfyui-camera-tools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Load Camera From File, Load 3D, Load 3D - Animation, Preview 3D, Preview 3D - Animation"
|
||||
},
|
||||
{
|
||||
"author": "ziwang-com",
|
||||
"title": "comfyui-deepseek-r1 [REMOVED]",
|
||||
"reference": "https://github.com/ziwang-com/comfyui-deepseek-r1",
|
||||
"files": [
|
||||
"https://github.com/ziwang-com/comfyui-deepseek-r1"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Comfyui-deepseek-r1 Node Plugin"
|
||||
},
|
||||
{
|
||||
"author": "leeguandong",
|
||||
"title": "ComfyUI nodes to use Xverse [REMOVED]",
|
||||
"reference": "https://github.com/leeguandong/ComfyUI_Xverse",
|
||||
"files": [
|
||||
"https://github.com/leeguandong/ComfyUI_Xverse"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "The ComfyUI version of [a/XVerse](https://github.com/bytedance/XVerse)"
|
||||
},
|
||||
{
|
||||
"author": "Dehypnotic",
|
||||
"title": "Dehypnotic Save nodes [REMOVED]",
|
||||
"reference": "https://github.com/Dehypnotic/comfyui-dehypnotic-save-nodes",
|
||||
"files": [
|
||||
"https://github.com/Dehypnotic/comfyui-dehypnotic-save-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Save toolkit for audio, image, and video: MP3 audio export with VBR/CBR options, multi-format image saving with workflow/thumbnail metadata, and video + frame encoding (MP4/MKV/WEBM/MOV) — all sharing whitelist-safe paths and rich placeholder templating."
|
||||
},
|
||||
{
|
||||
"author": "znuost10",
|
||||
"title": "comfyui-multi-float-output [REMOVED]",
|
||||
"reference": "https://github.com/znuost10/comfyui-multi-float-output",
|
||||
"files": [
|
||||
"https://github.com/znuost10/comfyui-multi-float-output"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "System monitoring API endpoints for ComfyUI by otoy SKW"
|
||||
},
|
||||
{
|
||||
"author": "rakki194",
|
||||
"title": "ComfyUI_WolfSigmas [UNSAFE/REMOVED]",
|
||||
"reference": "https://github.com/rakki194/ComfyUI_WolfSigmas",
|
||||
"files": [
|
||||
"https://github.com/rakki194/ComfyUI_WolfSigmas"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This custom nodepack for ComfyUI provides a suite of tools for generating and manipulating sigma schedules for diffusion models. These nodes are particularly useful for fine-tuning the sampling process, experimenting with different step counts, and adapting schedules for specific models.[w/Security Warning: Remote Code Execution]"
|
||||
},
|
||||
{
|
||||
"author": "Maff3u",
|
||||
"title": "MattiaNodes - Points Editor On Cropped [REMOVED]",
|
||||
"reference": "https://github.com/Maff3u/MattiaNodes",
|
||||
"files": [
|
||||
"https://github.com/Maff3u/MattiaNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A standalone ComfyUI custom node for interactive coordinate editing with crop factor correction.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "rakki194",
|
||||
"title": "ComfyUI-ImageCompare [REMOVED]",
|
||||
"reference": "https://github.com/rakki194/ComfyUI-ImageCompare",
|
||||
"files": [
|
||||
"https://github.com/rakki194/ComfyUI-ImageCompare"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A simple custom node for ComfyUI that allows you to compare two images (or batches of images) side-by-side within the UI."
|
||||
},
|
||||
{
|
||||
"author": "APZmedia",
|
||||
"title": "NormalMapLightEstimator [REMOVED]",
|
||||
"reference": "https://github.com/APZmedia/Comfyui-LightDirection-estimation",
|
||||
"files": [
|
||||
"https://github.com/APZmedia/Comfyui-LightDirection-estimation"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A ComfyUI custom node for estimating light direction and quality from normal maps using luma masking. The system analyzes surface normals to infer lighting information for downstream tasks like adaptive relighting, directional masking, or stylized effects."
|
||||
},
|
||||
{
|
||||
"author": "APZmedia",
|
||||
"title": "ComfyUI APZmedia PSD Tools [REMOVED]",
|
||||
"reference": "https://github.com/APZmedia/APZmedia-ComfyUI-PSDtools",
|
||||
"files": [
|
||||
"https://github.com/APZmedia/APZmedia-ComfyUI-PSDtools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This extension provides PSD layer saving functionalities with mask support for ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "huixingyun",
|
||||
"title": "ComfyUI-HX-Pimg [REMOVED]",
|
||||
"reference": "https://github.com/huixingyun/ComfyUI-HX-Pimg",
|
||||
"files": [
|
||||
"https://github.com/huixingyun/ComfyUI-HX-Pimg"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Some custom nodes used for pimg (a comfyui controller deployed in huixingyun)."
|
||||
},
|
||||
{
|
||||
"author": "rvage",
|
||||
"title": "ComfyUI-RvToolsX [REMOVED]",
|
||||
"reference": "https://github.com/r-vage/ComfyUI-RvToolsX",
|
||||
"files": [
|
||||
"https://github.com/r-vage/ComfyUI-RvToolsX"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI custom nodes and utilities for workflow building, type conversions, checkpoint/pipe loaders and file utilities."
|
||||
},
|
||||
{
|
||||
"author": "usman2003",
|
||||
"title": "ComfyUI-RaceDetect [REMOVED]",
|
||||
"reference": "https://github.com/usman2003/ComfyUI-RaceDetect",
|
||||
"files": [
|
||||
"https://github.com/usman2003/ComfyUI-RaceDetect"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Race Detection V2"
|
||||
},
|
||||
{
|
||||
"author": "lihaoyun6",
|
||||
"title": "ComfyUI-CSV-Random-Picker [REMOVED]",
|
||||
"reference": "https://github.com/lihaoyun6/ComfyUI-CSV-Random-Picker",
|
||||
"files": [
|
||||
"https://github.com/lihaoyun6/ComfyUI-CSV-Random-Picker"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "String random picker for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "r-vage",
|
||||
"title": "ComfyUI-RvTools_v2 [REMOVED]",
|
||||
"reference": "https://github.com/r-vage/ComfyUI-RvTools_v2",
|
||||
"files": [
|
||||
"https://github.com/r-vage/ComfyUI-RvTools_v2"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "this node contains a lot of small little helpers like switches, passers and selectors that i use a lot to build my workflows."
|
||||
},
|
||||
{
|
||||
"author": "Yuxi Liu",
|
||||
"title": "comfyui-ddu [REMOVED]",
|
||||
"reference": "https://github.com/YL-Lyx/Comfyui-ddu-toolchain",
|
||||
"files": [
|
||||
"https://github.com/YL-Lyx/Comfyui-ddu-toolchain"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ai-driven toolchain for digital design and fabrication "
|
||||
},
|
||||
{
|
||||
"author": "lu64k",
|
||||
"title": "SK-Nodes [REMOVED]",
|
||||
"reference": "https://github.com/lu64k/SK-Nodes",
|
||||
"files": [
|
||||
"https://github.com/lu64k/SK-Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES:image select, Load AnyLLM, Ask LLM, OpenAI DAlle Node, SK Text_String, SK Random File Name"
|
||||
},
|
||||
{
|
||||
"author": "SiggEye",
|
||||
"title": "FaceCanon — Consistent Faces at Any Resolution [REMOVED]",
|
||||
"reference": "https://github.com/SiggEye/FaceCanon",
|
||||
"files": [
|
||||
"https://github.com/SiggEye/FaceCanon"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "FaceCanon scales a detected face to a canonical pixel size, lets you run your favorite face detailer at that sweet spot, then maps the result back into the original image with seamless blending. The payoff is consistent face style no matter the input resolution or framing."
|
||||
},
|
||||
{
|
||||
"author": "AlfredClark",
|
||||
"title": "ComfyUI-ModelSpec [REMOVED]",
|
||||
"reference": "https://github.com/AlfredClark/ComfyUI-ModelSpec",
|
||||
"files": [
|
||||
"https://github.com/AlfredClark/ComfyUI-ModelSpec"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI model metadata editing nodes."
|
||||
},
|
||||
{
|
||||
"author": "VraethrDalkr",
|
||||
"title": "ComfyUI-ProgressiveBlend [REMOVED]",
|
||||
"reference": "https://github.com/VraethrDalkr/ComfyUI-ProgressiveBlend",
|
||||
"files": [
|
||||
"https://github.com/VraethrDalkr/ComfyUI-ProgressiveBlend"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of custom nodes for ComfyUI that enable progressive blending and color matching effects across image batches/video frames."
|
||||
},
|
||||
{
|
||||
"author": "xmarked-ai",
|
||||
"title": "ComfyUI_misc [REMOVED]",
|
||||
"reference": "https://github.com/xmarked-ai/ComfyUI_misc",
|
||||
"files": [
|
||||
"https://github.com/xmarked-ai/ComfyUI_misc"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Ace IntegerX, Ace FloatX, Ace Color FixX, White Balance X, Depth Displace X, Empty Latent X, KSampler Combo X, ..."
|
||||
},
|
||||
{
|
||||
"author": "sm079",
|
||||
"title": "ComfyUI-Face-Detection [REMOVED]",
|
||||
"reference": "https://github.com/sm079/ComfyUI-Face-Detection",
|
||||
"files": [
|
||||
"https://github.com/sm079/ComfyUI-Face-Detection"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "face detection nodes for comfyui"
|
||||
},
|
||||
{
|
||||
"author": "42lux",
|
||||
"title": "ComfyUI-42lux [REMOVED]",
|
||||
"reference": "https://github.com/42lux/ComfyUI-42lux",
|
||||
"files": [
|
||||
"https://github.com/42lux/ComfyUI-42lux"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of custom nodes for ComfyUI focused on enhanced sampling, model optimization, and quality improvements."
|
||||
},
|
||||
{
|
||||
"author": "lucak5s",
|
||||
"title": "ComfyUI GFPGAN [REMOVED]",
|
||||
"reference": "https://github.com/lucak5s/comfyui_gfpgan",
|
||||
"files": [
|
||||
"https://github.com/lucak5s/comfyui_gfpgan"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Face restoration with GFPGAN."
|
||||
},
|
||||
{
|
||||
"author": "impactframes",
|
||||
"title": "IF_AI_tools [DEPRECATED]",
|
||||
"id": "impactframes-tools",
|
||||
"reference": "https://github.com/if-ai/ComfyUI-IF_AI_tools",
|
||||
"files": [
|
||||
"https://github.com/if-ai/ComfyUI-IF_AI_tools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Various AI tools to use in Comfy UI. Starting with VL and prompt making tools using Ollma as backend will evolve as I find time."
|
||||
},
|
||||
{
|
||||
"author": "netroxin",
|
||||
"title": "comfyui_netro [REMOVED]",
|
||||
"reference": "https://github.com/netroxin/comfyui_netro",
|
||||
"files": [
|
||||
"https://github.com/netroxin/comfyui_netro"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "#Camera Movement Prompt Node for ComfyUI\nThis custom node script for ComfyUI generates descriptive camera movement prompts based on user-selected movement options for Wan2.2"
|
||||
},
|
||||
{
|
||||
"author": "aistudynow",
|
||||
"title": "comfyui-HunyuanImage-2.1 [REMOVED]",
|
||||
@ -672,16 +1357,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "This node provides advanced text-to-speech functionality powered by KokoroTTS. Follow the instructions below to install, configure, and use the node within your portable ComfyUI installation."
|
||||
},
|
||||
{
|
||||
"author": "MushroomFleet",
|
||||
"title": "DJZ-Pedalboard [REMOVED]",
|
||||
"reference": "https://github.com/MushroomFleet/DJZ-Pedalboard",
|
||||
"files": [
|
||||
"https://github.com/MushroomFleet/DJZ-Pedalboard"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This project provides a collection of custom nodes designed for enhanced audio effects in ComfyUI. With an intuitive pedalboard interface, users can easily integrate and manipulate various audio effects within their workflows."
|
||||
},
|
||||
{
|
||||
"author": "MushroomFleet",
|
||||
"title": "SVG Suite for ComfyUI [REMOVED]",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -361,6 +361,16 @@
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Vibe Coded ComfyUI Custom Nodes"
|
||||
},
|
||||
{
|
||||
"author": "aiforhumans",
|
||||
"title": "XDev Nodes - Complete Toolkit",
|
||||
"reference": "https://github.com/aiforhumans/comfyui-xdev-nodes",
|
||||
"files": [
|
||||
"https://github.com/aiforhumans/comfyui-xdev-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Complete ComfyUI development toolkit with 8 professional nodes including VAE tools, universal type testing, and comprehensive debugging infrastructure."
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
||||
[project]
|
||||
name = "comfyui-manager"
|
||||
license = { text = "GPL-3.0-only" }
|
||||
version = "4.0.3b1"
|
||||
version = "4.0.3b2"
|
||||
requires-python = ">= 3.9"
|
||||
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
||||
readme = "README.md"
|
||||
|
||||
@ -2,7 +2,7 @@ GitPython
|
||||
PyGithub
|
||||
# matrix-nio
|
||||
transformers
|
||||
huggingface-hub>0.20
|
||||
huggingface-hub
|
||||
typer
|
||||
rich
|
||||
typing-extensions
|
||||
|
||||
410
scanner.py
410
scanner.py
@ -7,13 +7,15 @@ import concurrent
|
||||
import datetime
|
||||
import concurrent.futures
|
||||
import requests
|
||||
import warnings
|
||||
import argparse
|
||||
|
||||
builtin_nodes = set()
|
||||
|
||||
import sys
|
||||
|
||||
from urllib.parse import urlparse
|
||||
from github import Github
|
||||
from github import Github, Auth
|
||||
|
||||
|
||||
def download_url(url, dest_folder, filename=None):
|
||||
@ -39,26 +41,51 @@ def download_url(url, dest_folder, filename=None):
|
||||
raise Exception(f"Failed to download file from {url}")
|
||||
|
||||
|
||||
# prepare temp dir
|
||||
if len(sys.argv) > 1:
|
||||
temp_dir = sys.argv[1]
|
||||
else:
|
||||
temp_dir = os.path.join(os.getcwd(), ".tmp")
|
||||
def parse_arguments():
|
||||
"""Parse command-line arguments"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description='ComfyUI Manager Node Scanner',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog='''
|
||||
Examples:
|
||||
# Standard mode
|
||||
python3 scanner.py
|
||||
python3 scanner.py --skip-update
|
||||
|
||||
if not os.path.exists(temp_dir):
|
||||
os.makedirs(temp_dir)
|
||||
# Scan-only mode
|
||||
python3 scanner.py --scan-only temp-urls-clean.list
|
||||
python3 scanner.py --scan-only urls.list --temp-dir /custom/temp
|
||||
python3 scanner.py --scan-only urls.list --skip-update
|
||||
'''
|
||||
)
|
||||
|
||||
parser.add_argument('--scan-only', type=str, metavar='URL_LIST_FILE',
|
||||
help='Scan-only mode: provide URL list file (one URL per line)')
|
||||
parser.add_argument('--temp-dir', type=str, metavar='DIR',
|
||||
help='Temporary directory for cloned repositories')
|
||||
parser.add_argument('--skip-update', action='store_true',
|
||||
help='Skip git clone/pull operations')
|
||||
parser.add_argument('--skip-stat-update', action='store_true',
|
||||
help='Skip GitHub stats collection')
|
||||
parser.add_argument('--skip-all', action='store_true',
|
||||
help='Skip all update operations')
|
||||
|
||||
# Backward compatibility: positional argument for temp_dir
|
||||
parser.add_argument('temp_dir_positional', nargs='?', metavar='TEMP_DIR',
|
||||
help='(Legacy) Temporary directory path')
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
skip_update = '--skip-update' in sys.argv or '--skip-all' in sys.argv
|
||||
skip_stat_update = '--skip-stat-update' in sys.argv or '--skip-all' in sys.argv
|
||||
|
||||
if not skip_stat_update:
|
||||
g = Github(os.environ.get('GITHUB_TOKEN'))
|
||||
else:
|
||||
g = None
|
||||
|
||||
|
||||
print(f"TEMP DIR: {temp_dir}")
|
||||
# Module-level variables (will be set in main if running as script)
|
||||
args = None
|
||||
scan_only_mode = False
|
||||
url_list_file = None
|
||||
temp_dir = None
|
||||
skip_update = False
|
||||
skip_stat_update = True
|
||||
g = None
|
||||
|
||||
|
||||
parse_cnt = 0
|
||||
@ -73,12 +100,22 @@ def extract_nodes(code_text):
|
||||
parse_cnt += 1
|
||||
|
||||
code_text = re.sub(r'\\[^"\']', '', code_text)
|
||||
parsed_code = ast.parse(code_text)
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('ignore', category=SyntaxWarning)
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
||||
parsed_code = ast.parse(code_text)
|
||||
|
||||
# Support both ast.Assign and ast.AnnAssign (for type-annotated assignments)
|
||||
assignments = (node for node in parsed_code.body if isinstance(node, (ast.Assign, ast.AnnAssign)))
|
||||
|
||||
assignments = (node for node in parsed_code.body if isinstance(node, ast.Assign))
|
||||
|
||||
for assignment in assignments:
|
||||
if isinstance(assignment.targets[0], ast.Name) and assignment.targets[0].id in ['NODE_CONFIG', 'NODE_CLASS_MAPPINGS']:
|
||||
# Handle ast.AnnAssign (e.g., NODE_CLASS_MAPPINGS: Type = {...})
|
||||
if isinstance(assignment, ast.AnnAssign):
|
||||
if isinstance(assignment.target, ast.Name) and assignment.target.id in ['NODE_CONFIG', 'NODE_CLASS_MAPPINGS']:
|
||||
node_class_mappings = assignment.value
|
||||
break
|
||||
# Handle ast.Assign (e.g., NODE_CLASS_MAPPINGS = {...})
|
||||
elif isinstance(assignment.targets[0], ast.Name) and assignment.targets[0].id in ['NODE_CONFIG', 'NODE_CLASS_MAPPINGS']:
|
||||
node_class_mappings = assignment.value
|
||||
break
|
||||
else:
|
||||
@ -90,7 +127,7 @@ def extract_nodes(code_text):
|
||||
for key in node_class_mappings.keys:
|
||||
if key is not None and isinstance(key.value, str):
|
||||
s.add(key.value.strip())
|
||||
|
||||
|
||||
return s
|
||||
else:
|
||||
return set()
|
||||
@ -98,6 +135,99 @@ def extract_nodes(code_text):
|
||||
return set()
|
||||
|
||||
|
||||
def has_comfy_node_base(class_node):
|
||||
"""Check if class inherits from io.ComfyNode or ComfyNode"""
|
||||
for base in class_node.bases:
|
||||
# Case 1: ComfyNode
|
||||
if isinstance(base, ast.Name) and base.id == 'ComfyNode':
|
||||
return True
|
||||
# Case 2: io.ComfyNode
|
||||
elif isinstance(base, ast.Attribute):
|
||||
if base.attr == 'ComfyNode':
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def extract_keyword_value(call_node, keyword):
|
||||
"""
|
||||
Extract string value of keyword argument
|
||||
Schema(node_id="MyNode") -> "MyNode"
|
||||
"""
|
||||
for kw in call_node.keywords:
|
||||
if kw.arg == keyword:
|
||||
# ast.Constant (Python 3.8+)
|
||||
if isinstance(kw.value, ast.Constant):
|
||||
if isinstance(kw.value.value, str):
|
||||
return kw.value.value
|
||||
# ast.Str (Python 3.7-) - suppress deprecation warning
|
||||
else:
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
||||
if hasattr(ast, 'Str') and isinstance(kw.value, ast.Str):
|
||||
return kw.value.s
|
||||
return None
|
||||
|
||||
|
||||
def is_schema_call(call_node):
|
||||
"""Check if ast.Call is io.Schema() or Schema()"""
|
||||
func = call_node.func
|
||||
if isinstance(func, ast.Name) and func.id == 'Schema':
|
||||
return True
|
||||
elif isinstance(func, ast.Attribute) and func.attr == 'Schema':
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def extract_node_id_from_schema(class_node):
|
||||
"""
|
||||
Extract node_id from define_schema() method
|
||||
"""
|
||||
for item in class_node.body:
|
||||
if isinstance(item, ast.FunctionDef) and item.name == 'define_schema':
|
||||
# Walk through function body
|
||||
for stmt in ast.walk(item):
|
||||
if isinstance(stmt, ast.Call):
|
||||
# Check if it's Schema() call
|
||||
if is_schema_call(stmt):
|
||||
node_id = extract_keyword_value(stmt, 'node_id')
|
||||
if node_id:
|
||||
return node_id
|
||||
return None
|
||||
|
||||
|
||||
def extract_v3_nodes(code_text):
|
||||
"""
|
||||
Extract V3 node IDs using AST parsing
|
||||
Returns: set of node_id strings
|
||||
"""
|
||||
global parse_cnt
|
||||
|
||||
try:
|
||||
if parse_cnt % 100 == 0:
|
||||
print(".", end="", flush=True)
|
||||
parse_cnt += 1
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('ignore', category=SyntaxWarning)
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
||||
tree = ast.parse(code_text)
|
||||
except (SyntaxError, UnicodeDecodeError):
|
||||
return set()
|
||||
|
||||
nodes = set()
|
||||
|
||||
# Find io.ComfyNode subclasses
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.ClassDef):
|
||||
# Check if inherits from ComfyNode
|
||||
if has_comfy_node_base(node):
|
||||
node_id = extract_node_id_from_schema(node)
|
||||
if node_id:
|
||||
nodes.add(node_id)
|
||||
|
||||
return nodes
|
||||
|
||||
|
||||
# scan
|
||||
def scan_in_file(filename, is_builtin=False):
|
||||
global builtin_nodes
|
||||
@ -105,13 +235,18 @@ def scan_in_file(filename, is_builtin=False):
|
||||
with open(filename, encoding='utf-8', errors='ignore') as file:
|
||||
code = file.read()
|
||||
|
||||
pattern = r"_CLASS_MAPPINGS\s*=\s*{([^}]*)}"
|
||||
# Support type annotations (e.g., NODE_CLASS_MAPPINGS: Type = {...}) and line continuations (\)
|
||||
pattern = r"_CLASS_MAPPINGS\s*(?::\s*\w+\s*)?=\s*(?:\\\s*)?{([^}]*)}"
|
||||
regex = re.compile(pattern, re.MULTILINE | re.DOTALL)
|
||||
|
||||
nodes = set()
|
||||
class_dict = {}
|
||||
|
||||
# V1 nodes detection
|
||||
nodes |= extract_nodes(code)
|
||||
|
||||
# V3 nodes detection
|
||||
nodes |= extract_v3_nodes(code)
|
||||
code = re.sub(r'^#.*?$', '', code, flags=re.MULTILINE)
|
||||
|
||||
def extract_keys(pattern, code):
|
||||
@ -208,6 +343,53 @@ def get_nodes(target_dir):
|
||||
return py_files, directories
|
||||
|
||||
|
||||
def get_urls_from_list_file(list_file):
|
||||
"""
|
||||
Read URLs from list file for scan-only mode
|
||||
|
||||
Args:
|
||||
list_file (str): Path to URL list file (one URL per line)
|
||||
|
||||
Returns:
|
||||
list of tuples: [(url, "", None, None), ...]
|
||||
Format: (url, title, preemptions, nodename_pattern)
|
||||
- title: Empty string
|
||||
- preemptions: None
|
||||
- nodename_pattern: None
|
||||
|
||||
File format:
|
||||
https://github.com/owner/repo1
|
||||
https://github.com/owner/repo2
|
||||
# Comments starting with # are ignored
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If list_file does not exist
|
||||
"""
|
||||
if not os.path.exists(list_file):
|
||||
raise FileNotFoundError(f"URL list file not found: {list_file}")
|
||||
|
||||
urls = []
|
||||
with open(list_file, 'r', encoding='utf-8') as f:
|
||||
for line_num, line in enumerate(f, 1):
|
||||
line = line.strip()
|
||||
|
||||
# Skip empty lines and comments
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
|
||||
# Validate URL format (basic check)
|
||||
if not (line.startswith('http://') or line.startswith('https://')):
|
||||
print(f"WARNING: Line {line_num} is not a valid URL: {line}")
|
||||
continue
|
||||
|
||||
# Add URL with empty metadata
|
||||
# (url, title, preemptions, nodename_pattern)
|
||||
urls.append((line, "", None, None))
|
||||
|
||||
print(f"Loaded {len(urls)} URLs from {list_file}")
|
||||
return urls
|
||||
|
||||
|
||||
def get_git_urls_from_json(json_file):
|
||||
with open(json_file, encoding='utf-8') as file:
|
||||
data = json.load(file)
|
||||
@ -264,13 +446,43 @@ def clone_or_pull_git_repository(git_url):
|
||||
print(f"Failed to clone '{repo_name}': {e}")
|
||||
|
||||
|
||||
def update_custom_nodes():
|
||||
def update_custom_nodes(scan_only_mode=False, url_list_file=None):
|
||||
"""
|
||||
Update custom nodes by cloning/pulling repositories
|
||||
|
||||
Args:
|
||||
scan_only_mode (bool): If True, use URL list file instead of custom-node-list.json
|
||||
url_list_file (str): Path to URL list file (required if scan_only_mode=True)
|
||||
|
||||
Returns:
|
||||
dict: node_info mapping {repo_name: (url, title, preemptions, node_pattern)}
|
||||
"""
|
||||
if not os.path.exists(temp_dir):
|
||||
os.makedirs(temp_dir)
|
||||
|
||||
node_info = {}
|
||||
|
||||
git_url_titles_preemptions = get_git_urls_from_json('custom-node-list.json')
|
||||
# Select URL source based on mode
|
||||
if scan_only_mode:
|
||||
if not url_list_file:
|
||||
raise ValueError("url_list_file is required in scan-only mode")
|
||||
|
||||
git_url_titles_preemptions = get_urls_from_list_file(url_list_file)
|
||||
print("\n[Scan-Only Mode]")
|
||||
print(f" - URL source: {url_list_file}")
|
||||
print(" - GitHub stats: DISABLED")
|
||||
print(f" - Git clone/pull: {'ENABLED' if not skip_update else 'DISABLED'}")
|
||||
print(" - Metadata: EMPTY")
|
||||
else:
|
||||
if not os.path.exists('custom-node-list.json'):
|
||||
raise FileNotFoundError("custom-node-list.json not found")
|
||||
|
||||
git_url_titles_preemptions = get_git_urls_from_json('custom-node-list.json')
|
||||
print("\n[Standard Mode]")
|
||||
print(" - URL source: custom-node-list.json")
|
||||
print(f" - GitHub stats: {'ENABLED' if not skip_stat_update else 'DISABLED'}")
|
||||
print(f" - Git clone/pull: {'ENABLED' if not skip_update else 'DISABLED'}")
|
||||
print(" - Metadata: FULL")
|
||||
|
||||
def process_git_url_title(url, title, preemptions, node_pattern):
|
||||
name = os.path.basename(url)
|
||||
@ -382,46 +594,59 @@ def update_custom_nodes():
|
||||
if not skip_stat_update:
|
||||
process_git_stats(git_url_titles_preemptions)
|
||||
|
||||
# Git clone/pull for all repositories
|
||||
with concurrent.futures.ThreadPoolExecutor(11) as executor:
|
||||
for url, title, preemptions, node_pattern in git_url_titles_preemptions:
|
||||
executor.submit(process_git_url_title, url, title, preemptions, node_pattern)
|
||||
|
||||
py_url_titles_and_pattern = get_py_urls_from_json('custom-node-list.json')
|
||||
# .py file download (skip in scan-only mode - only process git repos)
|
||||
if not scan_only_mode:
|
||||
py_url_titles_and_pattern = get_py_urls_from_json('custom-node-list.json')
|
||||
|
||||
def download_and_store_info(url_title_preemptions_and_pattern):
|
||||
url, title, preemptions, node_pattern = url_title_preemptions_and_pattern
|
||||
name = os.path.basename(url)
|
||||
if name.endswith(".py"):
|
||||
node_info[name] = (url, title, preemptions, node_pattern)
|
||||
def download_and_store_info(url_title_preemptions_and_pattern):
|
||||
url, title, preemptions, node_pattern = url_title_preemptions_and_pattern
|
||||
name = os.path.basename(url)
|
||||
if name.endswith(".py"):
|
||||
node_info[name] = (url, title, preemptions, node_pattern)
|
||||
|
||||
try:
|
||||
download_url(url, temp_dir)
|
||||
except Exception:
|
||||
print(f"[ERROR] Cannot download '{url}'")
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(10) as executor:
|
||||
executor.map(download_and_store_info, py_url_titles_and_pattern)
|
||||
with concurrent.futures.ThreadPoolExecutor(10) as executor:
|
||||
executor.map(download_and_store_info, py_url_titles_and_pattern)
|
||||
|
||||
return node_info
|
||||
|
||||
|
||||
def gen_json(node_info):
|
||||
def gen_json(node_info, scan_only_mode=False):
|
||||
"""
|
||||
Generate extension-node-map.json from scanned node information
|
||||
|
||||
Args:
|
||||
node_info (dict): Repository metadata mapping
|
||||
scan_only_mode (bool): If True, exclude metadata from output
|
||||
"""
|
||||
# scan from .py file
|
||||
node_files, node_dirs = get_nodes(temp_dir)
|
||||
|
||||
comfyui_path = os.path.abspath(os.path.join(temp_dir, "ComfyUI"))
|
||||
node_dirs.remove(comfyui_path)
|
||||
node_dirs = [comfyui_path] + node_dirs
|
||||
# Only reorder if ComfyUI exists in the list
|
||||
if comfyui_path in node_dirs:
|
||||
node_dirs.remove(comfyui_path)
|
||||
node_dirs = [comfyui_path] + node_dirs
|
||||
|
||||
data = {}
|
||||
for dirname in node_dirs:
|
||||
py_files = get_py_file_paths(dirname)
|
||||
metadata = {}
|
||||
|
||||
|
||||
nodes = set()
|
||||
for py in py_files:
|
||||
nodes_in_file, metadata_in_file = scan_in_file(py, dirname == "ComfyUI")
|
||||
nodes.update(nodes_in_file)
|
||||
# Include metadata from .py files in both modes
|
||||
metadata.update(metadata_in_file)
|
||||
|
||||
dirname = os.path.basename(dirname)
|
||||
@ -436,17 +661,28 @@ def gen_json(node_info):
|
||||
if dirname in node_info:
|
||||
git_url, title, preemptions, node_pattern = node_info[dirname]
|
||||
|
||||
metadata['title_aux'] = title
|
||||
# Conditionally add metadata based on mode
|
||||
if not scan_only_mode:
|
||||
# Standard mode: include all metadata
|
||||
metadata['title_aux'] = title
|
||||
|
||||
if preemptions is not None:
|
||||
metadata['preemptions'] = preemptions
|
||||
if preemptions is not None:
|
||||
metadata['preemptions'] = preemptions
|
||||
|
||||
if node_pattern is not None:
|
||||
metadata['nodename_pattern'] = node_pattern
|
||||
if node_pattern is not None:
|
||||
metadata['nodename_pattern'] = node_pattern
|
||||
# Scan-only mode: metadata remains empty
|
||||
|
||||
data[git_url] = (nodes, metadata)
|
||||
else:
|
||||
print(f"WARN: {dirname} is removed from custom-node-list.json")
|
||||
# Scan-only mode: Repository not in node_info (expected behavior)
|
||||
# Construct URL from dirname (author_repo format)
|
||||
if '_' in dirname:
|
||||
parts = dirname.split('_', 1)
|
||||
git_url = f"https://github.com/{parts[0]}/{parts[1]}"
|
||||
data[git_url] = (nodes, metadata)
|
||||
else:
|
||||
print(f"WARN: {dirname} is removed from custom-node-list.json")
|
||||
|
||||
for file in node_files:
|
||||
nodes, metadata = scan_in_file(file)
|
||||
@ -459,13 +695,16 @@ def gen_json(node_info):
|
||||
|
||||
if file in node_info:
|
||||
url, title, preemptions, node_pattern = node_info[file]
|
||||
metadata['title_aux'] = title
|
||||
|
||||
if preemptions is not None:
|
||||
metadata['preemptions'] = preemptions
|
||||
|
||||
if node_pattern is not None:
|
||||
metadata['nodename_pattern'] = node_pattern
|
||||
# Conditionally add metadata based on mode
|
||||
if not scan_only_mode:
|
||||
metadata['title_aux'] = title
|
||||
|
||||
if preemptions is not None:
|
||||
metadata['preemptions'] = preemptions
|
||||
|
||||
if node_pattern is not None:
|
||||
metadata['nodename_pattern'] = node_pattern
|
||||
|
||||
data[url] = (nodes, metadata)
|
||||
else:
|
||||
@ -477,6 +716,10 @@ def gen_json(node_info):
|
||||
for extension in extensions:
|
||||
node_list_json_path = os.path.join(temp_dir, extension, 'node_list.json')
|
||||
if os.path.exists(node_list_json_path):
|
||||
# Skip if extension not in node_info (scan-only mode with limited URLs)
|
||||
if extension not in node_info:
|
||||
continue
|
||||
|
||||
git_url, title, preemptions, node_pattern = node_info[extension]
|
||||
|
||||
with open(node_list_json_path, 'r', encoding='utf-8') as f:
|
||||
@ -506,14 +749,16 @@ def gen_json(node_info):
|
||||
print("------------------------------------------------------")
|
||||
node_list_json = {}
|
||||
|
||||
metadata_in_url['title_aux'] = title
|
||||
# Conditionally add metadata based on mode
|
||||
if not scan_only_mode:
|
||||
metadata_in_url['title_aux'] = title
|
||||
|
||||
if preemptions is not None:
|
||||
metadata['preemptions'] = preemptions
|
||||
if preemptions is not None:
|
||||
metadata_in_url['preemptions'] = preemptions
|
||||
|
||||
if node_pattern is not None:
|
||||
metadata_in_url['nodename_pattern'] = node_pattern
|
||||
|
||||
if node_pattern is not None:
|
||||
metadata_in_url['nodename_pattern'] = node_pattern
|
||||
|
||||
nodes = list(nodes)
|
||||
nodes.sort()
|
||||
data[git_url] = (nodes, metadata_in_url)
|
||||
@ -523,12 +768,53 @@ def gen_json(node_info):
|
||||
json.dump(data, file, indent=4, sort_keys=True)
|
||||
|
||||
|
||||
print("### ComfyUI Manager Node Scanner ###")
|
||||
if __name__ == "__main__":
|
||||
# Parse arguments
|
||||
args = parse_arguments()
|
||||
|
||||
print("\n# Updating extensions\n")
|
||||
updated_node_info = update_custom_nodes()
|
||||
# Determine mode
|
||||
scan_only_mode = args.scan_only is not None
|
||||
url_list_file = args.scan_only if scan_only_mode else None
|
||||
|
||||
print("\n# 'extension-node-map.json' file is generated.\n")
|
||||
gen_json(updated_node_info)
|
||||
# Determine temp_dir
|
||||
if args.temp_dir:
|
||||
temp_dir = args.temp_dir
|
||||
elif args.temp_dir_positional:
|
||||
temp_dir = args.temp_dir_positional
|
||||
else:
|
||||
temp_dir = os.path.join(os.getcwd(), ".tmp")
|
||||
|
||||
print("\nDONE.\n")
|
||||
if not os.path.exists(temp_dir):
|
||||
os.makedirs(temp_dir)
|
||||
|
||||
# Determine skip flags
|
||||
skip_update = args.skip_update or args.skip_all
|
||||
skip_stat_update = args.skip_stat_update or args.skip_all or scan_only_mode
|
||||
|
||||
if not skip_stat_update:
|
||||
auth = Auth.Token(os.environ.get('GITHUB_TOKEN'))
|
||||
g = Github(auth=auth)
|
||||
else:
|
||||
g = None
|
||||
|
||||
print("### ComfyUI Manager Node Scanner ###")
|
||||
|
||||
if scan_only_mode:
|
||||
print(f"\n# [Scan-Only Mode] Processing URL list: {url_list_file}\n")
|
||||
else:
|
||||
print("\n# [Standard Mode] Updating extensions\n")
|
||||
|
||||
# Update/clone repositories and collect node info
|
||||
updated_node_info = update_custom_nodes(scan_only_mode, url_list_file)
|
||||
|
||||
print("\n# Generating 'extension-node-map.json'...\n")
|
||||
|
||||
# Generate extension-node-map.json
|
||||
gen_json(updated_node_info, scan_only_mode)
|
||||
|
||||
print("\n✅ DONE.\n")
|
||||
|
||||
if scan_only_mode:
|
||||
print("Output: extension-node-map.json (node mappings only)")
|
||||
else:
|
||||
print("Output: extension-node-map.json (full metadata)")
|
||||
Loading…
Reference in New Issue
Block a user