Compare commits

...

205 Commits

Author SHA1 Message Date
ComfyPlus
142380ba31
Merge 851371700a into bba55d4d5a 2025-12-13 00:40:43 +09:00
Dr.Lt.Data
bba55d4d5a update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-12-12 23:08:38 +09:00
Dr.Lt.Data
87111bd889 update DB 2025-12-12 22:09:35 +09:00
SKFRMSEHF
3661ffd3ab
Update custom-node-list.json (#2388) 2025-12-12 21:41:13 +09:00
Dr.Lt.Data
d8f111a5e3 bump version 2025-12-12 18:16:51 +09:00
Benjamin Lu
ae5565ce68
ComfyUI version listing + nightly current fix (#2334)
* Improve comfyui version listing

* Fix ComfyUI semver selection and stable update

* Fix nightly current detection on default branch

* Fix: use tag_ref.name explicitly and cache get_remote_name result

- Use tag_ref.name instead of tag_ref object for checkout
- Cache get_remote_name() result to avoid duplicate calls

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Dr.Lt.Data <dr.lt.data@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 18:15:12 +09:00
Dr.Lt.Data
e4c370a7d9 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-12-12 12:29:09 +09:00
Dr.Lt.Data
891005bcd3 fix(git): handle divergent branches safely during pull
- Use --ff-only flag to detect non-fast-forward situations
- Create backup branch before resetting divergent local branch
- Reset to remote branch when fast-forward is not possible
- Use time.strftime() instead of datetime for better compatibility
- Bump version to 3.38.2
2025-12-12 12:22:42 +09:00
Dr.Lt.Data
d3a4a7a0fa ruff fix 2025-12-12 12:11:52 +09:00
Dr.Lt.Data
10211d1a93 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-12-12 05:34:33 +09:00
Jean Kássio
7f019a932b
Add JK AceStep Nodes (#2365)
* Add ComfyUI_MusicTools

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-12 05:23:14 +09:00
Dr.Lt.Data
fae909de2f update DB 2025-12-12 05:11:37 +09:00
Dr.Lt.Data
d8455ef6e5 update DB 2025-12-12 04:53:07 +09:00
hkun
934c994783
Add new custom node: lora_downloader (#2363)
* {
    "author": "huihuihuiz",
    "title": "LoRA Downloader for ComfyUI",
    "id": "lora_downloader",
    "reference": "https://github.com/huihuihuiz/lora_downloader",
    "repo_url": "https://github.com/huihuihuiz/lora_downloader",
    "install_type": "git",
    "description": "A ComfyUI custom node for downloading and managing LoRA models directly within the UI."
}

* Change install_type from 'git' to 'git-clone'

* Update custom-node-list.json

* Delete Lora_Downloader entry from JSON map

Removed Lora_Downloader entry from extension-node-map.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-12 04:52:12 +09:00
Dr.Lt.Data
d0961d596d update DB 2025-12-12 04:47:24 +09:00
Denys
382df24764
Add ComfyUI Custom Node Color (#2382)
* Add ComfyUI Custom Node Color

Added a new custom node for ComfyUI.

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-12 04:46:31 +09:00
Dr.Lt.Data
bfcfa42125 update DB 2025-12-12 04:43:44 +09:00
Braeden
2333886c34
Add custom node for ComfyUI Load Image URL (#2380)
Added a new custom node entry for loading images from URLs and Files.
2025-12-12 04:42:45 +09:00
Dr.Lt.Data
0cdad3c886 update DB 2025-12-12 04:40:36 +09:00
Nakano Kenji
eee23c543b
Add ComfyUI-SimpleChat (#2377) 2025-12-12 04:39:53 +09:00
Dr.Lt.Data
f0a8812f5e update DB 2025-12-12 04:39:30 +09:00
Lord Lethris
a8d603f753
Add ComfyUI-lethris-dia2: Dia2 TTS & Captions Generator (#2366)
* Update custom-node-list.json

JSON entry for my Dia2 TTS + Captions Node

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-12 04:37:53 +09:00
Dr.Lt.Data
22acaa1d2c update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-12-10 18:39:42 +09:00
Dr.Lt.Data
fe791ccee9 improved: scanner.py, json-checker.py 2025-12-10 18:39:02 +09:00
Dr.Lt.Data
414557eee0 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-12-10 12:59:56 +09:00
Dr.Lt.Data
97d2741360 update DB 2025-12-10 09:15:11 +09:00
Dr.Lt.Data
b95e5f1eae db fixed 2025-12-10 09:02:20 +09:00
Dr.Lt.Data
43b200dc91 update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-12-08 23:28:26 +09:00
Dr.Lt.Data
29014699bb update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-12-08 22:04:11 +09:00
Dr.Lt.Data
5576672957 update DB 2025-12-08 21:45:05 +09:00
DayMan84
5002606861
Add ComfyUI-Ugromana node with details (#2361)
Hello,

I would like to add my new custom node ComfyUI-Usromana to the registry.

Node Details:

Name: ComfyUI-UmeAiRT-Sync
Description: The next-generation security, governance, permissions, and multi‑user control system for ComfyUI.

Repository: https://github.com/DayMan84/ComfyUI-Usgromana

Verification:
I have verified the JSON syntax locally using the "Use local DB" option in ComfyUI Manager. The node appears correctly in the list and installs without issues.

Thank you!
2025-12-08 21:44:11 +09:00
Dr.Lt.Data
ba0fb343ff update DB 2025-12-08 21:33:00 +09:00
UmeAiRT
17e5ae6bc2
Add ComfyUI-UmeAiRT-Sync (#2360) 2025-12-08 21:31:52 +09:00
akawana
7a0186efc8
Modify 'Keybinding Extra' to 'Folded prompts' (#2359)
Updated the title, reference, description, and tags for the 'Keybinding Extra' entry in the custom-node-list.json file.
2025-12-08 21:30:29 +09:00
Dr.Lt.Data
de64af4a68 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-12-07 21:32:58 +09:00
Dr.Lt.Data
4a852ac8a8 update DB 2025-12-07 21:30:06 +09:00
shootthesound
6784bfb98c
Add Realtime LoRA Trainer node to custom-node-list (#2352)
Added a new node for Realtime LoRA Trainer with details.
2025-12-07 21:29:07 +09:00
Dr.Lt.Data
c8f246d344 update DB 2025-12-07 21:28:09 +09:00
The Kraken
8b3d31a936
Add Kraken Discord Bot custom node (#2358) 2025-12-07 21:27:17 +09:00
Dr.Lt.Data
5e88d6445b update DB 2025-12-07 21:25:30 +09:00
ds
fd7dff88df
Add ComfyUI_DashuaiTools to custom-node-list.json (#2319)
This PR adds the ComfyUI_DashuaiTools custom node pack to the ComfyUI-Manager node list.
2025-12-07 21:24:06 +09:00
Dr.Lt.Data
8cfee1f483 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-12-07 07:36:12 +09:00
Matthew-X
cf4d8e6125
Workflow Importer (#2356)
* Add Workflow Importer node to custom-node-list.json

* Update custom-node-list.json

* Add entry for SDXL_sizing by Ser-Hilary

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-07 07:35:14 +09:00
Dr.Lt.Data
c0e8a41d2a update DB 2025-12-07 07:32:45 +09:00
Antonio Covelo
a02c27b1af
Add ShakaNodes utility tools for ComfyUI (#2353)
Added new ShakaNodes project with author and description to ComfyUI-Maanager
2025-12-07 07:32:07 +09:00
Dr.Lt.Data
712e1bac0d update DB 2025-12-07 07:30:31 +09:00
ameyukisora
513ea46cbe
Add ComfyUI-Empty-Latent-Advanced (#2351) 2025-12-07 07:28:19 +09:00
Dr.Lt.Data
b1919b6f95 update DB 2025-12-07 07:28:06 +09:00
Jean Kássio
43561d209b
Add ComfyUI_MusicTools (#2350) 2025-12-07 07:25:47 +09:00
Dr.Lt.Data
16dcbc5412 update DB 2025-12-07 07:25:11 +09:00
HALXP
c8dd2d5cad
Added new file to existing HALXP-Comfy custom node (#2341)
* Added HALXP-Comfy to the custom node lists

* Update custom-node-list.json

* Added new file (HALXP Monitor) to current custom node

HALXP Monitor lets you run a custom script on workflow Success or Error

* Added one new file to the custom tools (runmonitor)

Lets you run custom scripts on workflow success or error

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-07 07:22:18 +09:00
Dr.Lt.Data
4b37777066 update DB 2025-12-07 07:15:35 +09:00
Antonio Sorrentini
95ecd85a12
Add ComfyUI-LegionPower node with description (#2326) 2025-12-07 07:11:33 +09:00
Dr.Lt.Data
5c475e3c15 update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-12-05 19:03:46 +09:00
Dr.Lt.Data
f705ee6863 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-12-05 13:00:22 +09:00
akawana
1f67c18989
Add RGBYP Mask Editor to custom-node-list.json (#2347)
* Add RGBYP Mask Editor to custom-node-list.json

Added RGBYP Mask Editor entry with details and tags.

* Fix description formatting in custom-node-list.json
2025-12-05 12:53:08 +09:00
rjgoif
de6d451c5b
Update custom-node-list.json (#2346)
Adding a small node collection "Img Label Tools" to help users add text labels easily to their images and grids, making for better sharing on Reddit and other communities. 
Small pack, no extra files, no restrictions.
2025-12-05 12:52:04 +09:00
Dr.Lt.Data
580296d6f3 update DB 2025-12-05 12:51:41 +09:00
vramfcker
a9e28fbce3
Add Random Prompt Builder node to custom-node-list (#2340)
Added new node for Random Prompt Builder with detailed description.
2025-12-05 12:50:40 +09:00
Dr.Lt.Data
311779cb20 update DB 2025-12-05 12:50:28 +09:00
llikethat
d2f8a89e87
Add faceExtractor node for ComfyUI (#2339)
Added faceExtractor node for ComfyUI which identifies based on input image reference
2025-12-05 12:49:28 +09:00
Dr.Lt.Data
84c95bf322 update DB 2025-12-05 12:48:44 +09:00
Fatih Eke
f75c801955
Add ComfyUI-Hunyuan3D-v3 - Tencent Hunyuan 3D Global API support (#2345)
Co-authored-by: exedesign <exedesign@github.com>
2025-12-05 12:46:37 +09:00
fredlef
faa2f54371
Add ComfyUI FSL Nodes — Gemini chat & image generation, utilities (#2316)
* Add ComfyUI FSL Nodes to custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
Co-authored-by: Fred LeFevre <fred@example.com>
2025-12-05 12:41:08 +09:00
Dr.Lt.Data
4249ac193a improved: display a more user-friendly message 2025-12-05 07:01:01 +09:00
Dr.Lt.Data
c709274a28 update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-12-03 01:46:58 +09:00
Dr.Lt.Data
c8f05e79db update DB 2025-12-03 01:35:55 +09:00
ah-kun
4d2887e99f
Add ComfyUI-FailSafe-Translate-Node to custom-node-list (#2330) 2025-12-03 01:35:14 +09:00
Dr.Lt.Data
29256a5154 update DB 2025-12-03 01:33:18 +09:00
luxdelux7
82d42e4094
Add Forbidden Vision custom node pack (#2328)
* Add Forbidden Vision custom node pack

Custom face detection/segmentation models with enhancement nodes for ComfyUI.
Supports realistic, anime, and NSFW content.

* Update custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-03 01:32:34 +09:00
Dr.Lt.Data
53850fb627 update DB 2025-12-03 01:29:30 +09:00
Pondowner857
34b4c8ce46
Update custom-node-list.json (#2325) 2025-12-03 01:28:25 +09:00
Dr.Lt.Data
e944841054 update DB 2025-12-03 01:25:51 +09:00
llikethat
f6a5ff5552
added iSeeBetter Custom Node (#2324)
* added iSeeBetter Custom Node

iSeeBetter Custom Node for upscaling

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-03 01:24:38 +09:00
Dr.Lt.Data
01763b59d4 update DB 2025-12-03 01:24:18 +09:00
BuddyBytes.co
044173b2a1
Add Smart Resolution Toolkit aspect-aware, snap64-safe resolution and latent generator nodes (#2322)
Smart Resolution Toolkit for ComfyUI

A lightweight resolution assistant for ComfyUI that provides human-friendly dropdowns to pick:

- Resolution presets: HD, FullHD, 2K, 4K, 8K
- Aspect ratios: 1:1, 9:16, 4:5, 21:9, 16:9, 2:3, etc.

Key Features:
• Auto width & height calculation (INT output)
• Latent-safe – automatically snaps to nearest multiple of 64
• Perfect for EmptyLatentImage, KSampler, AnimateDiff, ControlNet, Video formats
• Includes two nodes:
   - Smart Resolution Picker → returns width & height (INT)
   - Smart Latent Generator → directly creates empty LATENT tensor

Popular use cases:
TikTok video, IG story, portrait photography, ultra-wide banners, cinematic 21:9, album covers.

GitHub: https://github.com/buddy-bytes/ComfyUI-SmartResolutionToolkit
2025-12-03 01:20:12 +09:00
Dr.Lt.Data
99e7a88dbd update DB 2025-12-03 01:19:09 +09:00
HALXP
01cd9fbb0e
Add HALXP-Comfy to custom-node-list.json (#2320)
* Added HALXP-Comfy to the custom node lists

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-12-03 01:18:02 +09:00
Dr.Lt.Data
aaed1dc3d5
feat(security): Support System User Protection API with security migration (V3.38) (#2338)
- Migrate Manager data path: default/ComfyUI-Manager → __manager
- Force security_level=strong on outdated ComfyUI (block installations)
- Auto-migrate config.ini only; backup legacy files for manual verification
- Raise weak/normal- to normal during migration
- Add /manager/startup_alerts API for UI warnings
- Differentiate 403 responses: comfyui_outdated vs security_level
- Block startup scripts execution on old ComfyUI

Requires ComfyUI v0.3.76+ for full functionality.
Backward compatible with older versions (uses legacy path).
2025-12-03 00:42:12 +09:00
Dr.Lt.Data
c8dce94c03 update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-12-01 12:23:52 +09:00
Dr.Lt.Data
06496d07b3 update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-11-29 01:43:52 +09:00
painter890602
a97f98c9cc
Add PainterFLF2V custom node (#2311)
* Update custom-node-list.json

* Update custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-29 01:23:25 +09:00
Dr.Lt.Data
8d0406f74f update DB 2025-11-28 18:32:02 +09:00
Dr.Lt.Data
c64d14701d update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-11-28 08:59:09 +09:00
Dr.Lt.Data
00332ae444 update DB 2025-11-28 08:02:05 +09:00
akawana
e8deb3d8fe
Add Utils Extra custom node to the list (#2313)
* Add Utils Extra custom node to the list

Added a new custom node entry for Utils Extra with details.

* Update description in custom-node-list.json

Expanded the description to include additional functionalities of the utility tools.
2025-11-28 08:00:38 +09:00
obvirm
8b234c99cf
Add ComfyUI-WhisperXX custom node entry (#2314)
* Add ComfyUI-WhisperXX custom node entry

Added a new custom node entry for ComfyUI-WhisperXX with details.

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-28 07:59:25 +09:00
Rzgar
1f986d9c45
Add entry for Qwen Image Size Picker (#2312) 2025-11-28 07:56:02 +09:00
Dr.Lt.Data
bacb8fb3cd update DB
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2025-11-27 00:23:54 +09:00
Dr.Lt.Data
e4a90089ab fixed: a bug where updating ComfyUI using Update: ComfyUI Stable Version did not updating ComfyUI's dependencies 2025-11-26 21:54:28 +09:00
Dr.Lt.Data
674b9f3705 update DB 2025-11-26 21:41:55 +09:00
Dr.Lt.Data
4941fb8aa0 fixed: scanner.py
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-11-26 08:58:02 +09:00
Dr.Lt.Data
183af0dfa5 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-11-25 12:59:01 +09:00
Dr.Lt.Data
45ac5429f8 "update DB" 2025-11-25 12:46:44 +09:00
Dr.Lt.Data
c771977a95 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-11-24 23:10:06 +09:00
Dr.Lt.Data
668d7bbb2c update DB 2025-11-24 22:56:38 +09:00
akawana
926cfabb58
Add Keybinding Extra (keyboard shortcut extension) (#2306)
* Add Keybinding Extra custom node

Added a new custom node for Keybinding Extra with relevant details.

* Enhance description for Keybinding Extra

Updated the description for the Keybinding Extra to provide more detail about its functionality.

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-24 22:55:44 +09:00
Dr.Lt.Data
a9a8d05115 update DB 2025-11-24 22:54:26 +09:00
Eric Rollei
e368f4366a
Add Download Tools for ComfyUI (#2298)
Added new download tools for ComfyUI with extensive features for media downloading and web scraping.
2025-11-24 22:51:50 +09:00
Dr.Lt.Data
dc5bddbc17 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2025-11-24 02:00:50 +09:00
icekiub-ai
358a480408
IcyHider Nodes (#2304)
* Update custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-24 00:17:22 +09:00
Dr.Lt.Data
c96fdb3c7a update DB 2025-11-22 10:36:00 +09:00
Dr.Lt.Data
c090abcc02 update DB 2025-11-22 09:46:14 +09:00
kjqwer
1ff02be35f
add node (#2282)
* add node

* add node
2025-11-22 09:45:21 +09:00
Dr.Lt.Data
10fbfb88f7 update DB 2025-11-22 09:43:20 +09:00
MadiatorLabs
9753df72ed
Added ComfyUI-RunpodDirect to node list (#2291) 2025-11-22 09:41:54 +09:00
Dr.Lt.Data
095cc3f792 Merge PR #2297: Add PDF Tools and update AAA Metadata System
Resolved merge conflict with PR #2297 by integrating:
- PDF Tools - Advanced PDF Processing & OCR (new entry)
- AAA Metadata System (updated with enhanced description and metadata)
- HYPIR Image Restoration (preserved from main branch)

All entries use consistent spacing and JSON formatting.
2025-11-22 09:33:58 +09:00
Dr.Lt.Data
656171037b
Update custom-node-list.json
HYPIR-ComfyUI was a separated PR.
2025-11-22 09:28:40 +09:00
Dr.Lt.Data
7ac10f9442 update DB 2025-11-22 09:25:07 +09:00
yuanyuan-spec
3925ba27b4
feat: Add HunyuanVideo-1.5 nodes (#2300)
* feat: Add HunyuanVideo-1.5 nodes

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <dr.lt.data@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-22 09:23:18 +09:00
Dr.Lt.Data
44ba79aa31 update DB 2025-11-22 09:15:50 +09:00
Eric Rollei
14d0e31268
Add HYPIR Image Restoration nodes to custom-node-list (#2299)
Added custom ComfyUI nodes for HYPIR image restoration, including details on author, title, reference, and description.
2025-11-22 09:12:27 +09:00
Dr.Lt.Data
033acffad1 update DB 2025-11-22 08:42:06 +09:00
Writili
d29ff808a5
I added my node to the JSON file (#2287)
* Update custom-node-list.json

Added my node to the JSON

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-22 08:40:35 +09:00
Dr.Lt.Data
dc9b6d655b update DB 2025-11-22 08:40:02 +09:00
Casual Gamer
d340c85013
feat: add ComfyUI Text Processor to node list (#2295) 2025-11-22 08:39:00 +09:00
Dr.Lt.Data
e328353664 update DB 2025-11-21 00:33:43 +09:00
Eric Rollei
02785af8fd
Merge pull request #2 from EricRollei/EricRollei-patch-1
Add HYPIR Image Restoration entry to custom-node-list
2025-11-20 01:39:02 -08:00
Eric Rollei
736ae5d63e
Add HYPIR Image Restoration entry to custom-node-list
Added a new entry for HYPIR Image Restoration including author, title, reference, files, install type, description, and nodename pattern.
2025-11-20 01:38:39 -08:00
Eric Rollei
e1eeb617d2
Merge pull request #1 from EricRollei/EricRollei-patch-1
Add AAA Metadata System entry to custom-node-list
2025-11-20 01:34:27 -08:00
Eric Rollei
23b6c7f0de
Add AAA Metadata System entry to custom-node-list
Added a new entry for the AAA Metadata System with detailed features and installation instructions.
2025-11-20 01:34:04 -08:00
Eric Rollei
997f97e1fc
Add PDF Tools for advanced PDF processing and OCR
Added a new entry for advanced PDF processing tools, including OCR and image parsing capabilities.
2025-11-20 01:10:01 -08:00
Dr.Lt.Data
ff335ff1a0 update DB 2025-11-19 23:12:01 +09:00
Dr.Lt.Data
cb3036ef81 modified: scanner.py – updated main so it can be imported 2025-11-19 22:43:28 +09:00
Dr.Lt.Data
f762906188 update DB 2025-11-19 22:42:14 +09:00
cellzero
dde7920f8c
Add ComfyUI-Animon node (#2293)
* Add ComfyUI-Animon node

* Update custom-node-list.json

* Remove and re-add ComfyUI-Animon entry in JSON

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-19 22:41:13 +09:00
Dr.Lt.Data
1a0d24110a update DB 2025-11-19 22:38:35 +09:00
Devin Garner
e79f6c4471
Add new node for ComfyUI_Make-It-Animatable (#2292)
* Add new node for ComfyUI_Make-It-Animatable

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-19 22:37:20 +09:00
Dr.Lt.Data
a8a7024a84 update DB 2025-11-19 18:46:14 +09:00
Dr.Lt.Data
d93d002da0 improved: scanner.py - bugfix about preemption and support extraction only mode 2025-11-19 13:00:26 +09:00
Dr.Lt.Data
baaa0479e8 update DB 2025-11-19 01:43:47 +09:00
Dr.Lt.Data
cc3bd7a056 update DB 2025-11-18 12:59:21 +09:00
Dr.Lt.Data
4ecefb3b71 improved: scanner.py - supports scanning v3 nodes 2025-11-18 12:48:02 +09:00
Dr.Lt.Data
f24b5aa251 update DB 2025-11-17 12:27:39 +09:00
Dr.Lt.Data
de547da4cd update DB 2025-11-17 00:37:26 +09:00
Dr.Lt.Data
0f884166a6 update DB 2025-11-16 23:03:10 +09:00
Alan Kent
63379f759d
Added 360 interactive crop tool. (#2285) 2025-11-16 23:02:22 +09:00
Dr.Lt.Data
8fdff20243 update DB 2025-11-16 23:01:34 +09:00
Grafting Rayman
5dfa07ca03
Updates to the existing details (#2286)
* Update custom-node-list.json

* Update custom-node-list.json

* Update custom-node-list.json

* Update custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-16 23:00:03 +09:00
Dr.Lt.Data
343645be6a update DB 2025-11-16 22:58:58 +09:00
Wei Deng
91bf21d7a8
Add ComfyUI-MiVolo-V2 node details to JSON (#2283) 2025-11-16 22:57:30 +09:00
Dr.Lt.Data
be6516cfd3 update DB 2025-11-15 13:32:22 +09:00
Dr.Lt.Data
61f1e516a3 update DB 2025-11-15 08:27:09 +09:00
Grafting Rayman
73b2278b45
Update custom-node-list.json (#2275)
* Update custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-15 08:25:44 +09:00
Dr.Lt.Data
aa625e30b6 update DB 2025-11-15 08:25:30 +09:00
mercu-lore
29a46fe4ce
Update custom-node-list.json (#2279)
* Update custom-node-list.json

* Update custom-node-list.json

* Update BoxBox ID in custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-15 08:22:12 +09:00
Dr.Lt.Data
5b3ee49530 update DB 2025-11-15 08:21:27 +09:00
Owl-V
a9158a101f
feat: add ComfyUI-MultiTranslator (replaces ComfyUI-Translator) (#2278)
This PR addresses two issues with the previous ComfyUI-Translator entry:

Missing id field — caused the plugin to be invisible in ComfyUI-Manager's Install tab.
Naming conflict — the original name ComfyUI-Translator overlaps with other translation plugins, leading to user confusion.
The repository has been renamed to ComfyUI-MultiTranslator to better reflect its multi-engine capability and avoid conflicts.

This PR removes the old entry and adds a new, fully compliant one with a unique id.
2025-11-15 08:20:31 +09:00
Carmine Cristallo Scalzi
feed8abb34
Add iamccs annotate node — ComfyUI annotation extension (#2254)
* feat: Add IAMCCS-nodes repository (WANAnimate LoRA Loader Fix)

This repo adds a node fixing LoRA loading in native WANAnimate workflows without using WanVideoWrapper. Critical for FLUX/WAN 2.1 users.

* Update custom-node-list.json

* feat: Add IAMCCS annotate node to the list

* Update custom-node-list.json

---------

Co-authored-by: IAMCCS <info@carminecristalloscalzi.com>
Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-15 08:16:01 +09:00
Dr.Lt.Data
70decc740f update DB 2025-11-13 00:27:19 +09:00
Dr.Lt.Data
5b5c83f8c5 update DB 2025-11-12 23:52:37 +09:00
Takahiro Yano
773c06f40d
Add ComfyUI Fast Mosaic Detector node (#2274)
Added a new custom node for ComfyUI that provides high-speed mosaic detection with multiple modes.
2025-11-12 23:51:34 +09:00
Dr.Lt.Data
737e6ad5ed update DB 2025-11-12 23:50:51 +09:00
Creepybits
81bca9c94e
Update custom-node-list.json (#2273)
* Update custom-node-list.json

* Modify 'world weaver' node details in JSON

Updated the 'id' and 'install_type' fields for the 'world weaver' node.

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-12 23:50:10 +09:00
Dr.Lt.Data
eef0654de2 update DB 2025-11-12 23:49:43 +09:00
Dr.Lt.Data
997a00b8a2 update DB 2025-11-12 23:48:24 +09:00
RafaCost3D
4d25232c5f
This adds rafacostcomfy nodes DreamOmni2 GGUF (#2272)
* This adds rafacostcomfy nodes, which adds support to DreamOmni2 GGUF VLM models

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-12 23:47:44 +09:00
Dr.Lt.Data
135befa101 update DB 2025-11-12 23:45:41 +09:00
Owl-V
44cac3fc43
Add a set of translator nodes (#2271)
* Add a set of translator nodes

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-12 23:44:49 +09:00
Dr.Lt.Data
449fa3510e update DB 2025-11-12 23:42:29 +09:00
painter890602
d958af8aad
Add ComfyUI-Painterl2V to custom-node-list (#2267)
* Update custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-12 23:41:30 +09:00
Dr.Lt.Data
09f8d5cb2d update DB 2025-11-11 01:56:51 +09:00
Dr.Lt.Data
aedc99cefd bump version 2025-11-11 00:42:32 +09:00
unclepomedev
b32cab6e9a
Fix: Gracefully handle errors during pip package enumeration (#2266) 2025-11-11 00:41:16 +09:00
Dr.Lt.Data
a95186965e update DB 2025-11-11 00:40:41 +09:00
Bulldog68
7067de1bb2
request to add the node comfyui fmj llm in the manager. (#2265)
* Add FMJ-LLM node for Olama interaction

Added a new node for FMJ-LLM with details about its functionality and installation.

* Add FMJ-LLM node for Olama interaction

Added new node for FMJ-LLM with details for installation and usage.

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-11 00:39:36 +09:00
Dr.Lt.Data
f45d878d21 update DB 2025-11-11 00:39:23 +09:00
Usonaki
a0532b938d
Update custom-node-list.json to point to Usonaki fork (#2264)
Co-authored-by: Usonaki <you@example.com>
2025-11-11 00:37:32 +09:00
Dr.Lt.Data
6ad12b7652 update DB 2025-11-11 00:37:15 +09:00
Bulldog68
02887c6c9b
Add FMJ-speed-Prompt node to custom-node-list (#2263)
* Add FMJ-speed-Prompt node to custom-node-list

Added a new node for FMJ-speed-Prompt with details.

* Fix JSON structure for FMJ-speed-Prompt entry

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-11 00:35:29 +09:00
Dr.Lt.Data
1b645e1cc3 update DB 2025-11-11 00:31:40 +09:00
Uygar
0a4b2a0488
Update custom-node-list.json (#2268)
Added ComfyUI-Artha Nodes
2025-11-11 00:29:52 +09:00
Alex Furer
d4ce6ddc52
Add ComfyUI AF - Enhanced-HTML-Note node (#2269)
Added new ComfyUI custom node for enhanced HTML notes.
2025-11-11 00:28:44 +09:00
Dr.Lt.Data
5a5b989533 update DB 2025-11-11 00:27:17 +09:00
Owl-V
b57cffb0fa
feat: add ComfyUI-Owlv_Nodes (#2270)
* feat: add ComfyUI-Owlv_Nodes

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-11 00:25:53 +09:00
Dr.Lt.Data
72aa95cacf update DB 2025-11-10 12:56:58 +09:00
Dr.Lt.Data
14ef448937 update DB 2025-11-08 13:51:59 +09:00
fllywaay
1c10607c06
Add My Comfyui-TextLine-counter node (#2253)
* Update custom-node-list.json

* Update custom-node-list.json

* Update custom-node-list.json

* Remove 'id' field from Comfyui-TextLine-counter

Removed 'id' field from the Comfyui-TextLine-counter entry.

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-08 13:40:13 +09:00
Dr.Lt.Data
41e53a1f2a update DB 2025-11-08 13:40:04 +09:00
mikesimone
cde83e9a38
Add ComfyUI-LinkModeToggle custom node (#2260)
* Update custom-node-list.json

* Update custom-node-list.json

Renamed LinkModeToggle to ComfyUI-LinkModeToggle.

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-08 13:36:58 +09:00
Dr.Lt.Data
6c206b1c72 update DB 2025-11-08 13:36:48 +09:00
Hansheng Chen
a474219e7b
Add ComfyUI-piFlow node to custom-node-list.json (#2261) 2025-11-08 13:35:57 +09:00
Dr.Lt.Data
3b8d25eb31 update DB 2025-11-08 13:34:23 +09:00
mercu-lore
0faa0aa668
Add multiple angle camera control node (#2262)
* Add multiple angle camera control node

Added a new node for multiple angle camera control with detailed description and installation type.

* Remove duplicate entry for Multiple-Angle-Camera-Control

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-08 13:33:08 +09:00
Dr.Lt.Data
0fcdcc93a2 update DB 2025-11-07 12:37:02 +09:00
Dr.Lt.Data
461d5e72fe update DB 2025-11-07 00:42:18 +09:00
Dr.Lt.Data
3f030a2121 update DB 2025-11-06 00:37:25 +09:00
Dr.Lt.Data
7fb8e8662f update DB 2025-11-05 07:48:33 +09:00
Dr.Lt.Data
dd3ab9cff2 update DB 2025-11-05 00:33:32 +09:00
Dr.Lt.Data
97b518de12 update DB 2025-11-04 23:25:04 +09:00
Dr.Lt.Data
d2a795c866 update DB 2025-11-04 07:54:26 +09:00
Amir Ferdos
8a3d65be20
Add ComfyUI-GRAG-ArchAi3D custom node (#2252)
* Add ComfyUI-ArchAi3d-Qwen custom nodes

* Add new node entry for ComfyUI-GRAG-ArchAi3D

Adding GRAG (Guided Region-Adaptive Guidance) custom node with:
- Simple and Unified controllers
- Advanced sampler
- 54 presets
- Per-layer and adaptive control

* Update custom-node-list.json

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-04 07:32:06 +09:00
Dr.Lt.Data
b2126d8ba5 update DB 2025-11-03 18:23:26 +09:00
Dr.Lt.Data
6386411d21 update DB 2025-11-03 12:33:07 +09:00
Dr.Lt.Data
4250244136 update DB 2025-11-03 07:40:01 +09:00
Dr.Lt.Data
77c4f9993d update DB 2025-11-02 12:26:36 +09:00
Dr.Lt.Data
c7c8417577 update DB 2025-11-02 08:49:24 +09:00
Dr.Lt.Data
9d0985ded8 update DB 2025-11-01 13:39:08 +09:00
方长君
3663e10e33
Change Custom Node github address (#2247)
* Add MultiSaveImage custom node

* feat: change nodes github address and name

* Update custom-node-list.json

---------

Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
2025-11-01 11:55:55 +09:00
Dr.Lt.Data
5f37a82c3c update DB 2025-11-01 11:47:07 +09:00
Dr.Lt.Data
026bf1dfd7 update DB 2025-10-31 12:58:49 +09:00
Dr.Lt.Data
643a6e5080 update DB 2025-10-31 08:01:20 +09:00
Alex Furer
5267502896
Remove AF - Edit Generated Prompt node entry (#2245)
Removed 'AF - Edit Generated Prompt' node entry from the custom node list, as it's being migrated to a node pack and summitted via official registry
2025-10-31 07:41:26 +09:00
Dr.Lt.Data
c3c152122d update DB 2025-10-30 07:53:35 +09:00
killf
851371700a Update custom-node-list.json 2024-10-23 10:53:44 +08:00
28 changed files with 56167 additions and 11522 deletions

View File

@ -5,6 +5,7 @@
![menu](https://raw.githubusercontent.com/ltdrdata/ComfyUI-extension-tutorials/refs/heads/Main/ComfyUI-Manager/images/dialog.jpg)
## NOTICE
* V3.38: **Security patch** - Manager data migrated to protected path. See [Migration Guide](docs/en/v3.38-userdata-security-migration.md).
* V3.16: Support for `uv` has been added. Set `use_uv` in `config.ini`.
* V3.10: `double-click feature` is removed
* This feature has been moved to https://github.com/ltdrdata/comfyui-connection-helper
@ -140,20 +141,27 @@ This repository provides Colab notebooks that allow you to install and use Comfy
## Paths
In `ComfyUI-Manager` V3.0 and later, configuration files and dynamically generated files are located under `<USER_DIRECTORY>/default/ComfyUI-Manager/`.
Starting from V3.38, Manager uses a protected system path for enhanced security.
* <USER_DIRECTORY>
* If executed without any options, the path defaults to ComfyUI/user.
* It can be set using --user-directory <USER_DIRECTORY>.
* <USER_DIRECTORY>
* If executed without any options, the path defaults to ComfyUI/user.
* It can be set using --user-directory <USER_DIRECTORY>.
* Basic config files: `<USER_DIRECTORY>/default/ComfyUI-Manager/config.ini`
* Configurable channel lists: `<USER_DIRECTORY>/default/ComfyUI-Manager/channels.ini`
* Configurable pip overrides: `<USER_DIRECTORY>/default/ComfyUI-Manager/pip_overrides.json`
* Configurable pip blacklist: `<USER_DIRECTORY>/default/ComfyUI-Manager/pip_blacklist.list`
* Configurable pip auto fix: `<USER_DIRECTORY>/default/ComfyUI-Manager/pip_auto_fix.list`
* Saved snapshot files: `<USER_DIRECTORY>/default/ComfyUI-Manager/snapshots`
* Startup script files: `<USER_DIRECTORY>/default/ComfyUI-Manager/startup-scripts`
* Component files: `<USER_DIRECTORY>/default/ComfyUI-Manager/components`
| ComfyUI Version | Manager Path |
|-----------------|--------------|
| v0.3.76+ (with System User API) | `<USER_DIRECTORY>/__manager/` |
| Older versions | `<USER_DIRECTORY>/default/ComfyUI-Manager/` |
* Basic config files: `config.ini`
* Configurable channel lists: `channels.list`
* Configurable pip overrides: `pip_overrides.json`
* Configurable pip blacklist: `pip_blacklist.list`
* Configurable pip auto fix: `pip_auto_fix.list`
* Saved snapshot files: `snapshots/`
* Startup script files: `startup-scripts/`
* Component files: `components/`
> **Note**: See [Migration Guide](docs/en/v3.38-userdata-security-migration.md) for upgrade details.
## `extra_model_paths.yaml` Configuration

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,230 @@
# ComfyUI-Manager V3.38: Userdata Security Migration Guide
## Introduction
ComfyUI-Manager V3.38 introduces a **security patch** that migrates Manager's configuration and data to a protected system path. This change leverages ComfyUI's new System User Protection API (PR #10966) to provide enhanced security isolation.
This guide explains what happens during the migration and how to handle various situations.
---
## What Changed
### Finding Your Paths
When ComfyUI starts, it displays the full paths in the terminal:
```
** User directory: /path/to/ComfyUI/user
** ComfyUI-Manager config path: /path/to/ComfyUI/user/__manager/config.ini
```
Look for these lines in your startup log to find the exact location on your system. In this guide, paths are shown relative to the `user` directory.
### Path Migration
| Data | Legacy Path | New Path |
|------|-------------|----------|
| Configuration | `user/default/ComfyUI-Manager/` | `user/__manager/` |
| Snapshots | `user/default/ComfyUI-Manager/snapshots/` | `user/__manager/snapshots/` |
### Why This Change
In older ComfyUI versions, the `default/` directory was **unprotected** and accessible via web APIs. If you ran ComfyUI with `--listen 0.0.0.0` or similar options to allow external connections, this data **may have been tampered with** by malicious actors.
**Note:** If you only used ComfyUI locally (without `--listen` or with `--listen 127.0.0.1`), your data was not exposed to this vulnerability.
The new `__manager` path uses ComfyUI's protected system directory, which:
- **Cannot be accessed** from outside (protected by ComfyUI)
- Isolates system settings from user data
- Enables stricter security for remote access
**This is why only `config.ini` is automatically migrated** - other files (snapshots) may have been compromised and should be manually verified before copying.
---
## Automatic Migration
When you start ComfyUI with the new System User Protection API, Manager automatically handles the migration:
### Step 1: Configuration Migration
Only `config.ini` is migrated automatically.
**Important**: Snapshots are **NOT** automatically migrated. You must copy them manually if needed.
### Step 2: Security Level Check
During migration, if your security level is below `normal` (i.e., `weak` or `normal-`), it will be automatically raised to `normal`. This is a safety measure because the security level setting itself may have been tampered with in the old version.
```
======================================================================
[ComfyUI-Manager] WARNING: Security level adjusted
- Previous: 'weak' → New: 'normal'
- Raised to prevent unauthorized remote access.
======================================================================
```
If you need a lower security level, you can manually edit the config after migration.
### Step 3: Legacy Backup
Your entire legacy directory is moved to a backup location:
```
user/__manager/.legacy-manager-backup/
```
This backup is preserved until you manually delete it.
---
## Persistent Backup Notification
As long as the backup exists, Manager will remind you on **every startup**:
```
----------------------------------------------------------------------
[ComfyUI-Manager] NOTICE: Legacy backup exists
- Your old Manager data was backed up to:
/path/to/ComfyUI/user/__manager/.legacy-manager-backup
- Please verify and remove it when no longer needed.
----------------------------------------------------------------------
```
**To stop this notification**: Delete the `.legacy-manager-backup` folder inside `user/__manager/` after confirming you don't need any data from it.
---
## Recovering Old Data
### Snapshots
If you need your old snapshots, copy the contents of `.legacy-manager-backup/snapshots/` to `user/__manager/snapshots/`.
---
## Outdated ComfyUI Warning
If you're running an older version of ComfyUI without the System User Protection API, Manager will:
1. **Force security level to `strong`** - All installations are blocked
2. **Display warning message**:
```
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[ComfyUI-Manager] ERROR: ComfyUI version is outdated!
- Most operations are blocked for security.
- ComfyUI update is still allowed.
- Please update ComfyUI to use Manager normally.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
```
**Solution**: Update ComfyUI to v0.3.76 or later.
---
## Security Levels
| Level | What's Allowed |
|-------|----------------|
| `strong` | ComfyUI update only. All other installations blocked. |
| `normal` | Install/update/remove registered custom nodes and models. |
| `normal-` | Above + Install via Git URL or pip (localhost only). |
| `weak` | All operations allowed, including from remote connections. |
**Notes:**
- `strong` is forced on outdated ComfyUI versions.
- `normal` is the default and recommended for most users.
- `normal-` is for developers who need to install unregistered nodes locally.
- `weak` should only be used in isolated development environments.
### Changing Security Level
Edit `user/__manager/config.ini`:
```ini
[default]
security_level = normal
```
---
## Error Messages
### "comfyui_outdated" (HTTP 403)
This error appears when:
- Your ComfyUI doesn't have the System User Protection API
- All installations are blocked until you update ComfyUI
**Solution**: Update ComfyUI to the latest version.
### "security_level" (HTTP 403)
This error appears when:
- Your security level blocks the requested operation
- For example, `strong` level blocks all installations
**Solution**: Lower your security level in config.ini if appropriate for your use case.
---
## Security Warning: Suspicious Path
If you see this error on an **older** ComfyUI:
```
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[ComfyUI-Manager] ERROR: Suspicious path detected!
- '__manager' exists with low security level: 'weak'
- Please verify manually:
/path/to/ComfyUI/user/__manager/config.ini
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
```
On older ComfyUI versions, the `__manager` directory is not normally created. If this directory exists, it may have been created externally. For safety, manually verify the contents of this directory before updating ComfyUI.
---
## Troubleshooting
### All my installations are blocked
**Check 1**: Is your ComfyUI updated?
- Old ComfyUI forces `security_level = strong`
- Update ComfyUI to resolve
**Check 2**: What's your security level?
- Check `user/__manager/config.ini`
- `security_level = strong` blocks all installations
### My snapshots are missing
Snapshots are not automatically migrated. You need to manually copy the `snapshots` folder from inside `.legacy-manager-backup` to the `user/__manager/` directory.
### I keep seeing the backup notification
Delete the `.legacy-manager-backup` folder inside `user/__manager/` after confirming you don't need any data from it.
### Snapshot restore is blocked
On old ComfyUI (without System User API), snapshot restore is blocked because security is forced to `strong`. Update ComfyUI to enable snapshot restore.
---
## File Structure Reference
```
user/
└── __manager/
├── config.ini # Manager configuration
├── channels.list # Custom node channels
├── snapshots/ # Environment snapshots
└── .legacy-manager-backup/ # Backup of old Manager data (temporary)
```
---
## Requirements
- **ComfyUI**: v0.3.76 or later (with System User Protection API)
- **ComfyUI-Manager**: V3.38 or later

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@ import subprocess
import sys
import os
import traceback
import time
import git
import json
@ -219,7 +220,14 @@ def gitpull(path):
repo.close()
return
remote.pull()
try:
repo.git.pull('--ff-only')
except git.GitCommandError:
backup_name = f'backup_{time.strftime("%Y%m%d_%H%M%S")}'
repo.create_head(backup_name)
print(f"[ComfyUI-Manager] Cannot fast-forward. Backup created: {backup_name}")
repo.git.reset('--hard', f'{remote_name}/{branch_name}')
print(f"[ComfyUI-Manager] Reset to {remote_name}/{branch_name}")
repo.git.submodule('update', '--init', '--recursive')
new_commit_hash = repo.head.commit.hexsha

22226
github-stats-cache.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -40,10 +40,11 @@ import cnr_utils
import manager_util
import git_utils
import manager_downloader
import manager_migration
from node_package import InstalledNodePackage
version_code = [3, 37]
version_code = [3, 38, 3]
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
@ -214,9 +215,10 @@ def update_user_directory(user_dir):
global manager_pip_blacklist_path
global manager_components_path
manager_files_path = os.path.abspath(os.path.join(user_dir, 'default', 'ComfyUI-Manager'))
manager_files_path = manager_migration.get_manager_path(user_dir)
if not os.path.exists(manager_files_path):
os.makedirs(manager_files_path)
manager_migration.run_migration_checks(user_dir, manager_files_path)
manager_snapshot_path = os.path.join(manager_files_path, "snapshots")
if not os.path.exists(manager_snapshot_path):
@ -1719,7 +1721,7 @@ def read_config():
manager_util.use_uv = default_conf['use_uv'].lower() == 'true' if 'use_uv' in default_conf else False
manager_util.bypass_ssl = get_bool('bypass_ssl', False)
return {
result = {
'http_channel_enabled': get_bool('http_channel_enabled', False),
'preview_method': default_conf.get('preview_method', manager_funcs.get_current_preview_method()).lower(),
'git_exe': default_conf.get('git_exe', ''),
@ -1739,6 +1741,8 @@ def read_config():
'security_level': default_conf.get('security_level', 'normal').lower(),
'db_mode': default_conf.get('db_mode', 'cache').lower(),
}
manager_migration.force_security_level_if_needed(result)
return result
except Exception:
import importlib.util
@ -1746,7 +1750,7 @@ def read_config():
manager_util.use_uv = importlib.util.find_spec("uv") is not None and platform.system() != "Windows"
manager_util.bypass_ssl = False
return {
result = {
'http_channel_enabled': False,
'preview_method': manager_funcs.get_current_preview_method(),
'git_exe': '',
@ -1766,6 +1770,8 @@ def read_config():
'security_level': 'normal', # strong | normal | normal- | weak
'db_mode': 'cache', # local | cache | remote
}
manager_migration.force_security_level_if_needed(result)
return result
def get_config():
@ -2247,9 +2253,17 @@ def git_pull(path):
current_branch = repo.active_branch
remote_name = current_branch.tracking_branch().remote_name
remote = repo.remote(name=remote_name)
remote.pull()
try:
repo.git.pull('--ff-only')
except git.GitCommandError:
branch_name = current_branch.name
backup_name = f'backup_{time.strftime("%Y%m%d_%H%M%S")}'
repo.create_head(backup_name)
logging.info(f"[ComfyUI-Manager] Cannot fast-forward. Backup created: {backup_name}")
repo.git.reset('--hard', f'{remote_name}/{branch_name}')
logging.info(f"[ComfyUI-Manager] Reset to {remote_name}/{branch_name}")
repo.git.submodule('update', '--init', '--recursive')
repo.close()
@ -2517,22 +2531,23 @@ def update_to_stable_comfyui(repo_path):
logging.error('\t'+branch.name)
return "fail", None
versions, current_tag, _ = get_comfyui_versions(repo)
if len(versions) == 0 or (len(versions) == 1 and versions[0] == 'nightly'):
versions, current_tag, latest_tag = get_comfyui_versions(repo)
if latest_tag is None:
logging.info("[ComfyUI-Manager] Unable to update to the stable ComfyUI version.")
return "fail", None
if versions[0] == 'nightly':
latest_tag = versions[1]
else:
latest_tag = versions[0]
if current_tag == latest_tag:
tag_ref = next((t for t in repo.tags if t.name == latest_tag), None)
if tag_ref is None:
logging.info(f"[ComfyUI-Manager] Unable to locate tag '{latest_tag}' in repository.")
return "fail", None
if repo.head.commit == tag_ref.commit:
return "skip", None
else:
logging.info(f"[ComfyUI-Manager] Updating ComfyUI: {current_tag} -> {latest_tag}")
repo.git.checkout(latest_tag)
repo.git.checkout(tag_ref.name)
execute_install_script("ComfyUI", repo_path, instant_execution=False, no_deps=False)
return 'updated', latest_tag
except:
traceback.print_exc()
@ -2664,9 +2679,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:
@ -3351,36 +3370,80 @@ async def restore_snapshot(snapshot_path, git_helper_extras=None):
def get_comfyui_versions(repo=None):
if repo is None:
repo = git.Repo(comfy_path)
repo = repo or git.Repo(comfy_path)
remote_name = None
try:
remote = get_remote_name(repo)
repo.remotes[remote].fetch()
remote_name = get_remote_name(repo)
repo.remotes[remote_name].fetch()
except:
logging.error("[ComfyUI-Manager] Failed to fetch ComfyUI")
versions = [x.name for x in repo.tags if x.name.startswith('v')]
def parse_semver(tag_name):
match = re.match(r'^v(\d+)\.(\d+)\.(\d+)$', tag_name)
return tuple(int(x) for x in match.groups()) if match else None
# nearest tag
versions = sorted(versions, key=lambda v: repo.git.log('-1', '--format=%ct', v), reverse=True)
versions = versions[:4]
def normalize_describe(tag_name):
if not tag_name:
return None
base = tag_name.split('-', 1)[0]
return base if parse_semver(base) else None
current_tag = repo.git.describe('--tags')
# Collect semver tags and sort descending (highest first)
semver_tags = []
for tag in repo.tags:
semver = parse_semver(tag.name)
if semver:
semver_tags.append((semver, tag.name))
semver_tags.sort(key=lambda x: x[0], reverse=True)
semver_tags = [name for _, name in semver_tags]
if current_tag not in versions:
versions = sorted(versions + [current_tag], key=lambda v: repo.git.log('-1', '--format=%ct', v), reverse=True)
versions = versions[:4]
latest_tag = semver_tags[0] if semver_tags else None
main_branch = repo.heads.master
latest_commit = main_branch.commit
latest_tag = repo.git.describe('--tags', latest_commit.hexsha)
try:
described = repo.git.describe('--tags')
except Exception:
described = ''
if latest_tag != versions[0]:
versions.insert(0, 'nightly')
else:
versions[0] = 'nightly'
try:
exact_tag = repo.git.describe('--tags', '--exact-match')
except Exception:
exact_tag = ''
head_is_default = False
if remote_name:
try:
default_head_ref = repo.refs[f'{remote_name}/HEAD']
default_commit = default_head_ref.reference.commit
head_is_default = repo.head.commit == default_commit
except Exception:
head_is_default = False
nearest_semver = normalize_describe(described)
exact_semver = exact_tag if parse_semver(exact_tag) else None
if head_is_default and not exact_tag:
current_tag = 'nightly'
else:
current_tag = exact_tag or described or 'nightly'
# Prepare semver list for display: top 4 plus the current/nearest semver if missing
display_semver_tags = semver_tags[:4]
if exact_semver and exact_semver not in display_semver_tags:
display_semver_tags.append(exact_semver)
elif nearest_semver and nearest_semver not in display_semver_tags:
display_semver_tags.append(nearest_semver)
versions = ['nightly']
if current_tag and not exact_semver and current_tag not in versions and current_tag not in display_semver_tags:
versions.append(current_tag)
for tag in display_semver_tags:
if tag not in versions:
versions.append(tag)
versions = versions[:6]
return versions, current_tag, latest_tag

356
glob/manager_migration.py Normal file
View File

@ -0,0 +1,356 @@
"""
ComfyUI-Manager migration module.
Handles migration from legacy paths to new __manager path structure.
"""
import os
import sys
import subprocess
import configparser
# Startup notices for notice board
startup_notices = [] # List of (message, level) tuples
def add_startup_notice(message, level='warning'):
"""Add a notice to be displayed on Manager notice board.
Args:
message: HTML-formatted message string
level: 'warning', 'error', 'info'
"""
global startup_notices
startup_notices.append((message, level))
# Cache for API check (computed once per session)
_cached_has_system_user_api = None
def has_system_user_api():
"""Check if ComfyUI has the System User Protection API (PR #10966).
Result is cached for performance.
"""
global _cached_has_system_user_api
if _cached_has_system_user_api is None:
try:
import folder_paths
_cached_has_system_user_api = hasattr(folder_paths, 'get_system_user_directory')
except Exception:
_cached_has_system_user_api = False
return _cached_has_system_user_api
def get_manager_path(user_dir):
"""Get the appropriate manager files path based on ComfyUI version.
Returns:
str: manager_files_path
"""
if has_system_user_api():
return os.path.abspath(os.path.join(user_dir, '__manager'))
else:
return os.path.abspath(os.path.join(user_dir, 'default', 'ComfyUI-Manager'))
def run_migration_checks(user_dir, manager_files_path):
"""Run all migration and security checks.
Call this after get_manager_path() to handle:
- Legacy config migration (new ComfyUI)
- Legacy backup notification (every startup)
- Suspicious directory detection (old ComfyUI)
- Outdated ComfyUI warning (old ComfyUI)
"""
if has_system_user_api():
migrated = migrate_legacy_config(user_dir, manager_files_path)
# Only check for legacy backup if migration didn't just happen
# (migration already shows backup location in its message)
if not migrated:
check_legacy_backup(manager_files_path)
else:
check_suspicious_manager(user_dir)
warn_outdated_comfyui()
def check_legacy_backup(manager_files_path):
"""Check for legacy backup and notify user to verify and remove it.
This runs on every startup to remind users about pending legacy backup.
"""
backup_dir = os.path.join(manager_files_path, '.legacy-manager-backup')
if not os.path.exists(backup_dir):
return
# Terminal output
print("\n" + "-"*70)
print("[ComfyUI-Manager] NOTICE: Legacy backup exists")
print(" - Your old Manager data was backed up to:")
print(f" {backup_dir}")
print(" - Please verify and remove it when no longer needed.")
print("-"*70 + "\n")
# Notice board output
add_startup_notice(
"Legacy ComfyUI-Manager data backup exists. Please verify and remove when no longer needed. See terminal for details.",
level='info'
)
def check_suspicious_manager(user_dir):
"""Check for suspicious __manager directory on old ComfyUI.
On old ComfyUI without System User API, if __manager exists with low security,
warn the user to verify manually.
Returns:
bool: True if suspicious setup detected
"""
if has_system_user_api():
return False # Not suspicious on new ComfyUI
suspicious_path = os.path.abspath(os.path.join(user_dir, '__manager'))
if not os.path.exists(suspicious_path):
return False
config_path = os.path.join(suspicious_path, 'config.ini')
if not os.path.exists(config_path):
return False
config = configparser.ConfigParser()
config.read(config_path)
sec_level = config.get('default', 'security_level', fallback='normal').lower()
if sec_level in ['weak', 'normal-']:
# Terminal output
print("\n" + "!"*70)
print("[ComfyUI-Manager] ERROR: Suspicious path detected!")
print(f" - '__manager' exists with low security level: '{sec_level}'")
print(" - Please verify manually:")
print(f" {config_path}")
print("!"*70 + "\n")
# Notice board output
add_startup_notice(
"[Security Alert] Suspicious path detected. See terminal log for details.",
level='error'
)
return True
return False
def warn_outdated_comfyui():
"""Warn user about outdated ComfyUI without System User API."""
if has_system_user_api():
return
# Terminal output
print("\n" + "!"*70)
print("[ComfyUI-Manager] ERROR: ComfyUI version is outdated!")
print(" - Most operations are blocked for security.")
print(" - ComfyUI update is still allowed.")
print(" - Please update ComfyUI to use Manager normally.")
print("!"*70 + "\n")
# Notice board output
add_startup_notice(
"[Security Alert] ComfyUI outdated. Installations blocked (update allowed).<BR>"
"Update ComfyUI for normal operation.",
level='error'
)
def migrate_legacy_config(user_dir, manager_files_path):
"""Migrate ONLY config.ini to new __manager path if needed.
IMPORTANT: Only config.ini is migrated. Other files (snapshots, cache, etc.)
are NOT migrated - users must recreate them.
Scenarios:
1. Legacy exists, New doesn't exist → Migrate config.ini
2. Legacy exists, New exists First update after upgrade
- Run ComfyUI dependency installation
- Rename legacy to .backup
3. Legacy doesn't exist → No migration needed
Returns:
bool: True if migration was performed
"""
if not has_system_user_api():
return False
legacy_dir = os.path.join(user_dir, 'default', 'ComfyUI-Manager')
legacy_config = os.path.join(legacy_dir, 'config.ini')
new_config = os.path.join(manager_files_path, 'config.ini')
if not os.path.exists(legacy_dir):
return False # No legacy directory, nothing to migrate
# IMPORTANT: Check for config.ini existence, not just directory
# (because makedirs() creates __manager before this function is called)
# Case: Both configs exist (first update after ComfyUI upgrade)
# This means user ran new ComfyUI at least once, creating __manager/config.ini
if os.path.exists(legacy_config) and os.path.exists(new_config):
_handle_first_update_migration(user_dir, legacy_dir, manager_files_path)
return True
# Case: Legacy config exists but new config doesn't (normal migration)
# This is the first run after ComfyUI upgrade
if os.path.exists(legacy_config) and not os.path.exists(new_config):
pass # Continue with normal migration below
else:
return False
# Terminal output
print("\n" + "-"*70)
print("[ComfyUI-Manager] NOTICE: Legacy config.ini detected")
print(f" - Old: {legacy_config}")
print(f" - New: {new_config}")
print(" - Migrating config.ini only (other files are NOT migrated).")
print(" - Security level below 'normal' will be raised.")
print("-"*70 + "\n")
_migrate_config_with_security_check(legacy_config, new_config)
# Move legacy directory to backup
_move_legacy_to_backup(legacy_dir, manager_files_path)
return True
def _handle_first_update_migration(user_dir, legacy_dir, manager_files_path):
"""Handle first ComfyUI update when both legacy and new directories exist.
This scenario happens when:
- User was on old ComfyUI (using default/ComfyUI-Manager)
- ComfyUI was updated (now has System User API)
- Manager already created __manager on first new run
- But legacy directory still exists
Actions:
1. Run ComfyUI dependency installation
2. Move legacy to __manager/.legacy-manager-backup
"""
# Terminal output
print("\n" + "-"*70)
print("[ComfyUI-Manager] NOTICE: First update after ComfyUI upgrade detected")
print(" - Both legacy and new directories exist.")
print(" - Running ComfyUI dependency installation...")
print("-"*70 + "\n")
# Run ComfyUI dependency installation
# Path: glob/manager_migration.py → glob → comfyui-manager → custom_nodes → ComfyUI
try:
comfyui_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
requirements_path = os.path.join(comfyui_path, 'requirements.txt')
if os.path.exists(requirements_path):
subprocess.run([sys.executable, '-m', 'pip', 'install', '-r', requirements_path],
capture_output=True, check=False)
print("[ComfyUI-Manager] ComfyUI dependencies installation completed.")
except Exception as e:
print(f"[ComfyUI-Manager] WARNING: Failed to install ComfyUI dependencies: {e}")
# Move legacy to backup inside __manager
_move_legacy_to_backup(legacy_dir, manager_files_path)
def _move_legacy_to_backup(legacy_dir, manager_files_path):
"""Move legacy directory to backup inside __manager.
Returns:
str: Path to backup directory if successful, None if failed
"""
import shutil
backup_dir = os.path.join(manager_files_path, '.legacy-manager-backup')
try:
if os.path.exists(backup_dir):
shutil.rmtree(backup_dir) # Remove old backup if exists
shutil.move(legacy_dir, backup_dir)
# Terminal output (full paths shown here only)
print("\n" + "-"*70)
print("[ComfyUI-Manager] NOTICE: Legacy settings migrated")
print(f" - Old location: {legacy_dir}")
print(f" - Backed up to: {backup_dir}")
print(" - Please verify and remove the backup when no longer needed.")
print("-"*70 + "\n")
# Notice board output (no full paths for security)
add_startup_notice(
"Legacy ComfyUI-Manager data migrated. See terminal for details.",
level='info'
)
return backup_dir
except Exception as e:
print(f"[ComfyUI-Manager] WARNING: Failed to backup legacy directory: {e}")
add_startup_notice(
f"[MIGRATION] Failed to backup legacy directory: {e}",
level='warning'
)
return None
def _migrate_config_with_security_check(legacy_path, new_path):
"""Migrate legacy config, raising security level only if below default."""
config = configparser.ConfigParser()
try:
config.read(legacy_path)
except Exception as e:
print(f"[ComfyUI-Manager] WARNING: Failed to parse config.ini: {e}")
print(" - Creating fresh config with default settings.")
add_startup_notice(
"[MIGRATION] Failed to parse legacy config. Using defaults.",
level='warning'
)
return # Skip migration, let Manager create fresh config
# Security level hierarchy: strong > normal > normal- > weak
# Default is 'normal', only raise if below default
if 'default' in config:
current_level = config['default'].get('security_level', 'normal').lower()
below_default_levels = ['weak', 'normal-']
if current_level in below_default_levels:
config['default']['security_level'] = 'normal'
# Terminal output
print("\n" + "="*70)
print("[ComfyUI-Manager] WARNING: Security level adjusted")
print(f" - Previous: '{current_level}' → New: 'normal'")
print(" - Raised to prevent unauthorized remote access.")
print("="*70 + "\n")
# Notice board output
add_startup_notice(
f"[MIGRATION] Security level raised: '{current_level}''normal'.<BR>"
"To prevent unauthorized remote access.",
level='warning'
)
else:
print(f" - Security level: '{current_level}' (no change needed)")
# Ensure directory exists
os.makedirs(os.path.dirname(new_path), exist_ok=True)
with open(new_path, 'w') as f:
config.write(f)
def force_security_level_if_needed(config_dict):
"""Force security level to 'strong' if on old ComfyUI.
Args:
config_dict: Configuration dictionary to modify in-place
Returns:
bool: True if security level was forced
"""
if not has_system_user_api():
config_dict['security_level'] = 'strong'
return True
return False

View File

@ -22,6 +22,7 @@ import asyncio
import queue
import manager_downloader
import manager_migration
logging.info(f"### Loading: ComfyUI-Manager ({core.version_str})")
@ -276,6 +277,13 @@ import zipfile
import urllib.request
def security_403_response():
"""Return appropriate 403 response based on ComfyUI version."""
if not manager_migration.has_system_user_api():
return web.json_response({"error": "comfyui_outdated"}, status=403)
return web.json_response({"error": "security_level"}, status=403)
def get_model_dir(data, show_log=False):
if 'download_model_base' in folder_paths.folder_names_and_paths:
models_base = folder_paths.folder_names_and_paths['download_model_base'][0][0]
@ -732,7 +740,7 @@ async def fetch_updates(request):
async def update_all(request):
if not is_allowed_security_level('middle'):
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
return web.Response(status=403)
return security_403_response()
with task_worker_lock:
is_processing = task_worker_thread is not None and task_worker_thread.is_alive()
@ -965,7 +973,7 @@ async def get_snapshot_list(request):
async def remove_snapshot(request):
if not is_allowed_security_level('middle'):
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
return web.Response(status=403)
return security_403_response()
try:
target = request.rel_url.query["target"]
@ -983,7 +991,7 @@ async def remove_snapshot(request):
async def restore_snapshot(request):
if not is_allowed_security_level('middle'):
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
return web.Response(status=403)
return security_403_response()
try:
target = request.rel_url.query["target"]
@ -1302,7 +1310,7 @@ async def fix_custom_node(request):
async def install_custom_node_git_url(request):
if not is_allowed_security_level('high'):
logging.error(SECURITY_MESSAGE_NORMAL_MINUS)
return web.Response(status=403)
return security_403_response()
url = await request.text()
res = await core.gitclone_install(url)
@ -1322,7 +1330,7 @@ async def install_custom_node_git_url(request):
async def install_custom_node_pip(request):
if not is_allowed_security_level('high'):
logging.error(SECURITY_MESSAGE_NORMAL_MINUS)
return web.Response(status=403)
return security_403_response()
packages = await request.text()
core.pip_install(packages.split(' '))
@ -1594,6 +1602,16 @@ async def get_notice(request):
except:
pass
# Prepend startup notices from manager_migration
for message, level in reversed(manager_migration.startup_notices):
if level == 'error':
style = 'color:red; background-color:white; font-weight:bold'
elif level == 'warning':
style = 'color:orange; background-color:white; font-weight:bold'
else:
style = 'color:blue; background-color:white'
markdown_content = f'<P style="{style}">{message}</P>' + markdown_content
return web.Response(text=markdown_content, status=200)
else:
return web.Response(text="Unable to retrieve Notice", status=200)
@ -1601,11 +1619,35 @@ async def get_notice(request):
return web.Response(text="Unable to retrieve Notice", status=200)
@routes.get("/manager/startup_alerts")
async def get_startup_alerts(request):
"""Return startup alerts for customAlert display on page load.
Returns JSON array of alerts that should be shown to user immediately.
All startup notices (error, warning, info) are returned.
"""
alerts = []
# Return all startup notices for alert display
for message, level in manager_migration.startup_notices:
# Convert HTML BR to newlines for customAlert
text = message.replace('<BR>', '\n').replace('<br>', '\n')
# Add [ComfyUI-Manager] prefix for customAlert (notice board shows in Manager UI anyway)
text = text.replace('[Security Alert]', '[ComfyUI-Manager] Security Alert:')
text = text.replace('[MIGRATION]', '[ComfyUI-Manager] Migration:')
alerts.append({
'message': text,
'level': level
})
return web.json_response(alerts)
@routes.get("/manager/reboot")
def restart(self):
if not is_allowed_security_level('middle'):
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
return web.Response(status=403)
return security_403_response()
try:
sys.stdout.close_log()

View File

@ -55,7 +55,7 @@ def get_pip_cmd(force_uv=False):
subprocess.check_output(test_cmd, stderr=subprocess.DEVNULL, timeout=5)
return [sys.executable] + (['-s'] if embedded else []) + ['-m', 'pip']
except Exception:
logging.warning("[ComfyUI-Manager] python -m pip not available. Falling back to uv.")
logging.warning("[ComfyUI-Manager] `python -m pip` not available. Falling back to `uv`.")
# Try uv (either forced or pip failed)
import shutil
@ -64,19 +64,19 @@ def get_pip_cmd(force_uv=False):
try:
test_cmd = [sys.executable] + (['-s'] if embedded else []) + ['-m', 'uv', '--version']
subprocess.check_output(test_cmd, stderr=subprocess.DEVNULL, timeout=5)
logging.info("[ComfyUI-Manager] Using uv as Python module for pip operations.")
logging.info("[ComfyUI-Manager] Using `uv` as Python module for pip operations.")
return [sys.executable] + (['-s'] if embedded else []) + ['-m', 'uv', 'pip']
except Exception:
pass
# Try standalone uv
if shutil.which('uv'):
logging.info("[ComfyUI-Manager] Using standalone uv for pip operations.")
logging.info("[ComfyUI-Manager] Using standalone `uv` for pip operations.")
return ['uv', 'pip']
# Nothing worked
logging.error("[ComfyUI-Manager] Neither python -m pip nor uv are available. Cannot proceed with package operations.")
raise Exception("Neither pip nor uv are available for package management")
logging.error("[ComfyUI-Manager] Neither `python -m pip` nor `uv` are available. Cannot proceed with package operations.")
raise Exception("Neither `pip` nor `uv` are available for package management")
def make_pip_cmd(cmd):

View File

@ -1,6 +1,6 @@
import { api } from "../../scripts/api.js";
import { app } from "../../scripts/app.js";
import { sleep, customConfirm, customAlert } from "./common.js";
import { sleep, customConfirm, customAlert, handle403Response, show_message } from "./common.js";
async function tryInstallCustomNode(event) {
let msg = '-= [ComfyUI Manager] extension installation request =-\n\n';
@ -42,7 +42,7 @@ async function tryInstallCustomNode(event) {
});
if(response.status == 403) {
show_message('This action is not allowed with this security level configuration.');
await handle403Response(response);
return false;
}
else if(response.status == 400) {
@ -54,7 +54,7 @@ async function tryInstallCustomNode(event) {
let response = await api.fetchApi("/manager/reboot");
if(response.status == 403) {
show_message('This action is not allowed with this security level configuration.');
await handle403Response(response);
return false;
}

View File

@ -14,7 +14,7 @@ import { OpenArtShareDialog } from "./comfyui-share-openart.js";
import {
free_models, install_pip, install_via_git_url, manager_instance,
rebootAPI, setManagerInstance, show_message, customAlert, customPrompt,
infoToast, showTerminal, setNeedRestart
infoToast, showTerminal, setNeedRestart, handle403Response
} from "./common.js";
import { ComponentBuilderDialog, getPureName, load_components, set_component_policy } from "./components-manager.js";
import { CustomNodesManager } from "./custom-nodes-manager.js";
@ -753,9 +753,9 @@ async function onQueueStatus(event) {
const rebootButton = document.getElementById('cm-reboot-button5');
rebootButton?.addEventListener("click",
function() {
if(rebootAPI()) {
manager_dialog.close();
async function() {
if(await rebootAPI()) {
manager_instance.close();
}
});
}
@ -780,8 +780,13 @@ async function updateAll(update_comfyui) {
const response = await api.fetchApi(`/manager/queue/update_all?mode=${mode}`);
if (response.status == 401) {
if (response.status == 403) {
await handle403Response(response);
reset_action_buttons();
}
else if (response.status == 401) {
customAlert('Another task is already in progress. Please stop the ongoing task first.');
reset_action_buttons();
}
else if(response.status == 200) {
is_updating = true;
@ -1453,6 +1458,31 @@ app.registerExtension({
load_components();
// Fetch and show startup alerts (critical errors like outdated ComfyUI)
// Poll until extensionManager.toast is ready (set in Vue onMounted)
const showStartupAlerts = async () => {
let toastWaitCount = 0;
const waitForToast = () => {
if (window['app']?.extensionManager?.toast) {
fetch('/manager/startup_alerts')
.then(response => response.ok ? response.json() : [])
.then(alerts => {
for (const alert of alerts) {
customAlert(alert.message);
}
})
.catch(e => console.warn('[ComfyUI-Manager] Failed to fetch startup alerts:', e));
} else if (toastWaitCount < 300) { // Max 30 seconds (300 * 100ms)
toastWaitCount++;
setTimeout(waitForToast, 100);
} else {
console.warn('[ComfyUI-Manager] Timeout waiting for toast. Startup alerts skipped.');
}
};
waitForToast();
};
showStartupAlerts();
const menu = document.querySelector(".comfy-menu");
const separator = document.createElement("hr");

View File

@ -100,6 +100,19 @@ export function show_message(msg) {
app.ui.dialog.element.style.zIndex = 1100;
}
export async function handle403Response(res, defaultMessage) {
try {
const data = await res.json();
if(data.error === 'comfyui_outdated') {
show_message('ComfyUI version is outdated.<BR>Please update ComfyUI to use Manager normally.');
} else {
show_message(defaultMessage || 'This action is not allowed with this security level configuration.');
}
} catch {
show_message(defaultMessage || 'This action is not allowed with this security level configuration.');
}
}
export async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
@ -163,20 +176,23 @@ export async function customPrompt(title, message) {
}
export function rebootAPI() {
export async function rebootAPI() {
if ('electronAPI' in window) {
window.electronAPI.restartApp();
return true;
}
customConfirm("Are you sure you'd like to reboot the server?").then((isConfirmed) => {
if (isConfirmed) {
try {
api.fetchApi("/manager/reboot");
const isConfirmed = await customConfirm("Are you sure you'd like to reboot the server?");
if (isConfirmed) {
try {
const response = await api.fetchApi("/manager/reboot");
if (response.status == 403) {
await handle403Response(response);
return false;
}
catch(exception) {}
}
});
catch(exception) {}
}
return false;
}
@ -216,7 +232,7 @@ export async function install_pip(packages) {
});
if(res.status == 403) {
show_message('This action is not allowed with this security level configuration.');
await handle403Response(res);
return;
}
@ -251,7 +267,7 @@ export async function install_via_git_url(url, manager_dialog) {
});
if(res.status == 403) {
show_message('This action is not allowed with this security level configuration.');
await handle403Response(res);
return;
}
@ -262,9 +278,9 @@ export async function install_via_git_url(url, manager_dialog) {
const self = this;
rebootButton.addEventListener("click",
function() {
if(rebootAPI()) {
manager_dialog.close();
async function() {
if(await rebootAPI()) {
manager_instance.close();
}
});
}

View File

@ -7,7 +7,7 @@ import {
fetchData, md5, icons, show_message, customConfirm, customAlert, customPrompt,
sanitizeHTML, infoToast, showTerminal, setNeedRestart,
storeColumnWidth, restoreColumnWidth, getTimeAgo, copyText, loadCss,
showPopover, hidePopover
showPopover, hidePopover, handle403Response
} from "./common.js";
// https://cenfun.github.io/turbogrid/api.html
@ -1528,7 +1528,16 @@ export class CustomNodesManager {
errorMsg = `'${item.title}': `;
if(res.status == 403) {
errorMsg += `This action is not allowed with this security level configuration.\n`;
try {
const data = await res.json();
if(data.error === 'comfyui_outdated') {
errorMsg += `ComfyUI version is outdated. Please update ComfyUI to use Manager normally.\n`;
} else {
errorMsg += `This action is not allowed with this security level configuration.\n`;
}
} catch {
errorMsg += `This action is not allowed with this security level configuration.\n`;
}
} else if(res.status == 404) {
errorMsg += `With the current security level configuration, only custom nodes from the <B>"default channel"</B> can be installed.\n`;
} else {

View File

@ -1,9 +1,9 @@
import { app } from "../../scripts/app.js";
import { $el } from "../../scripts/ui.js";
import {
manager_instance, rebootAPI,
import {
manager_instance, rebootAPI,
fetchData, md5, icons, show_message, customAlert, infoToast, showTerminal,
storeColumnWidth, restoreColumnWidth, loadCss
storeColumnWidth, restoreColumnWidth, loadCss, handle403Response
} from "./common.js";
import { api } from "../../scripts/api.js";
@ -477,7 +477,16 @@ export class ModelManager {
errorMsg = `'${item.name}': `;
if(res.status == 403) {
errorMsg += `This action is not allowed with this security level configuration.\n`;
try {
const data = await res.json();
if(data.error === 'comfyui_outdated') {
errorMsg += `ComfyUI version is outdated. Please update ComfyUI to use Manager normally.\n`;
} else {
errorMsg += `This action is not allowed with this security level configuration.\n`;
}
} catch {
errorMsg += `This action is not allowed with this security level configuration.\n`;
}
} else {
errorMsg += await res.text() + '\n';
}

View File

@ -1,7 +1,7 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
import { ComfyDialog, $el } from "../../scripts/ui.js";
import { manager_instance, rebootAPI, show_message } from "./common.js";
import { manager_instance, rebootAPI, show_message, handle403Response } from "./common.js";
async function restore_snapshot(target) {
@ -10,7 +10,7 @@ async function restore_snapshot(target) {
const response = await api.fetchApi(`/snapshot/restore?target=${target}`, { cache: "no-store" });
if(response.status == 403) {
show_message('This action is not allowed with this security level configuration.');
await handle403Response(response);
return false;
}
@ -38,7 +38,7 @@ async function remove_snapshot(target) {
const response = await api.fetchApi(`/snapshot/remove?target=${target}`, { cache: "no-store" });
if(response.status == 403) {
show_message('This action is not allowed with this security level configuration.');
await handle403Response(response);
return false;
}
@ -145,8 +145,8 @@ export class SnapshotManager extends ComfyDialog {
if(btn_id) {
const rebootButton = document.getElementById(btn_id);
const self = this;
rebootButton.onclick = function() {
if(rebootAPI()) {
rebootButton.onclick = async function() {
if(await rebootAPI()) {
self.close();
self.manager_dialog.close();
}

View File

@ -1,25 +1,264 @@
import json
import argparse
#!/usr/bin/env python3
"""JSON Entry Validator
def check_json_syntax(file_path):
Validates JSON entries based on content structure.
Validation rules based on JSON content:
- {"custom_nodes": [...]}: Validates required fields (author, title, reference, files, install_type, description)
- {"models": [...]}: Validates JSON syntax only (no required fields)
- Other JSON structures: Validates JSON syntax only
Git repository URL validation (for custom_nodes):
1. URLs must NOT end with .git
2. URLs must follow format: https://github.com/{author}/{reponame}
3. .py and .js files are exempt from this check
Supported formats:
- Array format: [{...}, {...}]
- Object format: {"custom_nodes": [...]} or {"models": [...]}
"""
import json
import re
import sys
from pathlib import Path
from typing import Dict, List, Tuple
# Required fields for each entry type
REQUIRED_FIELDS_CUSTOM_NODE = ['author', 'title', 'reference', 'files', 'install_type', 'description']
REQUIRED_FIELDS_MODEL = [] # model-list.json doesn't require field validation
# Pattern for valid GitHub repository URL (without .git suffix)
GITHUB_REPO_PATTERN = re.compile(r'^https://github\.com/[^/]+/[^/]+$')
def get_entry_context(entry: Dict) -> str:
"""Get identifying information from entry for error messages
Args:
entry: JSON entry
Returns:
String with author and reference info
"""
parts = []
if 'author' in entry:
parts.append(f"author={entry['author']}")
if 'reference' in entry:
parts.append(f"ref={entry['reference']}")
if 'title' in entry:
parts.append(f"title={entry['title']}")
if parts:
return " | ".join(parts)
else:
# No identifying info - show actual entry content (truncated)
import json
entry_str = json.dumps(entry, ensure_ascii=False)
if len(entry_str) > 100:
entry_str = entry_str[:100] + "..."
return f"content={entry_str}"
def validate_required_fields(entry: Dict, entry_index: int, required_fields: List[str]) -> List[str]:
"""Validate that all required fields are present
Args:
entry: JSON entry to validate
entry_index: Index of entry in array (for error reporting)
required_fields: List of required field names
Returns:
List of error descriptions (without entry prefix/context)
"""
errors = []
for field in required_fields:
if field not in entry:
errors.append(f"Missing required field '{field}'")
elif entry[field] is None:
errors.append(f"Field '{field}' is null")
elif isinstance(entry[field], str) and not entry[field].strip():
errors.append(f"Field '{field}' is empty")
elif field == 'files' and not entry[field]: # Empty array
errors.append("Field 'files' is empty array")
return errors
def validate_git_repo_urls(entry: Dict, entry_index: int) -> List[str]:
"""Validate git repository URLs in 'files' array
Requirements:
- Git repo URLs must NOT end with .git
- Must follow format: https://github.com/{author}/{reponame}
- .py and .js files are exempt
Args:
entry: JSON entry to validate
entry_index: Index of entry in array (for error reporting)
Returns:
List of error descriptions (without entry prefix/context)
"""
errors = []
if 'files' not in entry or not isinstance(entry['files'], list):
return errors
for file_url in entry['files']:
if not isinstance(file_url, str):
continue
# Skip .py and .js files - they're exempt from git repo validation
if file_url.endswith('.py') or file_url.endswith('.js'):
continue
# Check if it's a GitHub URL (likely a git repo)
if 'github.com' in file_url:
# Error if URL ends with .git
if file_url.endswith('.git'):
errors.append(f"Git repo URL must NOT end with .git: {file_url}")
continue
# Validate format: https://github.com/{author}/{reponame}
if not GITHUB_REPO_PATTERN.match(file_url):
errors.append(f"Invalid git repo URL format (expected https://github.com/author/reponame): {file_url}")
return errors
def validate_entry(entry: Dict, entry_index: int, required_fields: List[str]) -> List[str]:
"""Validate a single JSON entry
Args:
entry: JSON entry to validate
entry_index: Index of entry in array (for error reporting)
required_fields: List of required field names
Returns:
List of error messages (empty if valid)
"""
errors = []
# Check required fields
errors.extend(validate_required_fields(entry, entry_index, required_fields))
# Check git repository URLs
errors.extend(validate_git_repo_urls(entry, entry_index))
return errors
def validate_json_file(file_path: str) -> Tuple[bool, List[str]]:
"""Validate JSON file containing entries
Args:
file_path: Path to JSON file
Returns:
Tuple of (is_valid, error_messages)
"""
errors = []
# Check file exists
path = Path(file_path)
if not path.exists():
return False, [f"File not found: {file_path}"]
# Load JSON
try:
with open(file_path, 'r', encoding='utf-8') as file:
json_str = file.read()
json.loads(json_str)
print(f"[ OK ] {file_path}")
except UnicodeDecodeError as e:
print(f"Unicode decode error: {e}")
with open(path, 'r', encoding='utf-8') as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"[FAIL] {file_path}\n\n {e}\n")
except FileNotFoundError:
print(f"[FAIL] {file_path}\n\n File not found\n")
return False, [f"Invalid JSON: {e}"]
except Exception as e:
return False, [f"Error reading file: {e}"]
# Determine required fields based on JSON content
required_fields = []
# Validate structure - support both array and object formats
entries_to_validate = []
if isinstance(data, list):
# Direct array format: [{...}, {...}]
entries_to_validate = data
elif isinstance(data, dict):
# Object format: {"custom_nodes": [...]} or {"models": [...]}
# Determine validation based on keys
if 'custom_nodes' in data and isinstance(data['custom_nodes'], list):
required_fields = REQUIRED_FIELDS_CUSTOM_NODE
entries_to_validate = data['custom_nodes']
elif 'models' in data and isinstance(data['models'], list):
required_fields = REQUIRED_FIELDS_MODEL
entries_to_validate = data['models']
else:
# Other JSON structures (extension-node-map.json, etc.) - just validate JSON syntax
return True, []
else:
return False, ["JSON root must be either an array or an object containing arrays"]
# Validate each entry
for idx, entry in enumerate(entries_to_validate, start=1):
if not isinstance(entry, dict):
# Show actual value for type errors
entry_str = json.dumps(entry, ensure_ascii=False) if not isinstance(entry, str) else repr(entry)
if len(entry_str) > 150:
entry_str = entry_str[:150] + "..."
errors.append(f"\n❌ Entry #{idx}: Must be an object, got {type(entry).__name__}")
errors.append(f" Actual value: {entry_str}")
continue
entry_errors = validate_entry(entry, idx, required_fields)
if entry_errors:
# Group errors by entry with context
context = get_entry_context(entry)
errors.append(f"\n❌ Entry #{idx} ({context}):")
for error in entry_errors:
errors.append(f" - {error}")
is_valid = len(errors) == 0
return is_valid, errors
def main():
parser = argparse.ArgumentParser(description="JSON File Syntax Checker")
parser.add_argument("file_path", type=str, help="Path to the JSON file for syntax checking")
"""Main entry point"""
if len(sys.argv) < 2:
print("Usage: python json-checker.py <json-file>")
print("\nValidates JSON entries based on content:")
print(" - {\"custom_nodes\": [...]}: Validates required fields (author, title, reference, files, install_type, description)")
print(" - {\"models\": [...]}: Validates JSON syntax only (no required fields)")
print(" - Other JSON structures: Validates JSON syntax only")
print("\nGit repo URL validation (for custom_nodes):")
print(" - URLs must NOT end with .git")
print(" - URLs must follow: https://github.com/{author}/{reponame}")
sys.exit(1)
args = parser.parse_args()
check_json_syntax(args.file_path)
file_path = sys.argv[1]
if __name__ == "__main__":
is_valid, errors = validate_json_file(file_path)
if is_valid:
print(f"{file_path}: Validation passed")
sys.exit(0)
else:
print(f"Validating: {file_path}")
print("=" * 60)
print("❌ Validation failed!\n")
print("Errors:")
# Count actual errors (lines starting with " -")
error_count = sum(1 for e in errors if e.strip().startswith('-'))
for error in errors:
# Don't add ❌ prefix to grouped entries (they already have it)
if error.strip().startswith(''):
print(error)
else:
print(error)
print(f"\nTotal errors: {error_count}")
sys.exit(1)
if __name__ == '__main__':
main()

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

View File

@ -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)"
}
]
}

View File

@ -1,5 +1,496 @@
{
"custom_nodes": [
{
"author": "cdanielp",
"title": "COMFYUI_PROMPTMODELS [REMOVED]",
"reference": "https://github.com/cdanielp/COMFYUI_PROMPTMODELS",
"files": [
"https://github.com/cdanielp/COMFYUI_PROMPTMODELS"
],
"install_type": "git-clone",
"description": "Custom nodes for ComfyUI by PROMPTMODELS."
},
{
"author": "mcrataobrabo",
"title": "comfyui-smart-lora-downloader - Automatically Fetch Missing LoRAs [REMOVED]",
"reference": "https://github.com/mcrataobrabo/comfyui-smart-lora-downloader",
"files": [
"https://github.com/mcrataobrabo/comfyui-smart-lora-downloader"
],
"install_type": "git-clone",
"description": "Automatically detect and download missing LoRAs for ComfyUI workflows"
},
{
"author": "KANAsho34636",
"title": "ComfyUI-NaturalSort-ImageLoader [REMOVED]",
"reference": "https://github.com/KANAsho34636/ComfyUI-NaturalSort-ImageLoader",
"files": [
"https://github.com/KANAsho34636/ComfyUI-NaturalSort-ImageLoader"
],
"install_type": "git-clone",
"description": "Custom image loader node supporting natural number sorting with multiple sort modes (natural, lexicographic, modification time, creation time, reverse natural). (Description by CC)"
},
{
"author": "johninthewinter",
"title": "comfyui-fal-flux-2-John [REMOVED]",
"reference": "https://github.com/johninthewinter/comfyui-fal-flux-2-John",
"files": [
"https://github.com/johninthewinter/comfyui-fal-flux-2-John"
],
"install_type": "git-clone",
"description": "Custom nodes for ComfyUI that integrate with fal.ai's FLUX 2 and FLUX 1 LoRA APIs for text-to-image generation."
},
{
"author": "LargeModGames",
"title": "ComfyUI LoRA Auto Downloader [REMOVED]",
"reference": "https://github.com/LargeModGames/comfyui-smart-lora-downloader",
"files": [
"https://github.com/LargeModGames/comfyui-smart-lora-downloader"
],
"install_type": "git-clone",
"description": "Automatically download missing LoRAs from CivitAI and detect missing LoRAs in workflows. Features smart directory detection and easy installation."
},
{
"author": "DiffusionWave",
"title": "PickResolution_DiffusionWave [DEPRECATED]",
"reference": "https://github.com/DiffusionWave/PickResolution_DiffusionWave",
"files": [
"https://github.com/DiffusionWave/PickResolution_DiffusionWave"
],
"install_type": "git-clone",
"description": "A custom node for ComfyUI that allows selecting a base resolution, applying a custom scaling value based on FLOAT (up to 10 decimal places), and adding an extra integer value. Outputs include both INT and FLOAT resolutions, making it perfect for you to play around with."
},
{
"author": "geltz",
"title": "ComfyUI-geltz [REMOVED]",
"reference": "https://github.com/geltz/ComfyUI-geltz",
"files": [
"https://github.com/geltz/ComfyUI-geltz"
],
"install_type": "git-clone",
"description": "Various custom nodes; guidance, latents, sampling, tokenization, etc."
},
{
"author": "anilsathyan7",
"title": "ComfyUI-Crystal-Upscaler [REMOVED]",
"reference": "https://github.com/anilsathyan7/ComfyUI-Crystal-Upscaler",
"files": [
"https://github.com/anilsathyan7/ComfyUI-Crystal-Upscaler"
],
"install_type": "git-clone",
"description": "ComfyUI custom node for image upscaling using crystal upscaling technology. (Description by CC)"
},
{
"author": "nohikomiso",
"title": "ComfyUI-ImageFolderPicker [REMOVED/UNSAFE]",
"reference": "https://github.com/nohikomiso/ComfyUI-ImageFolderPicker",
"files": [
"https://github.com/nohikomiso/ComfyUI-ImageFolderPicker"
],
"install_type": "git-clone",
"description": "Custom ComfyUI node for browsing local server folders and selecting images via thumbnail display in a grid interface. (Description by CC)[w/This nodepack has a vulnerability that allows it to retrieve a list of files from arbitrary paths.]"
},
{
"author": "rzasharp79",
"title": "ComfyUI--SolarFlare [REMOVED]",
"reference": "https://github.com/rzasharp79/ComfyUI--SolarFlare",
"files": [
"https://github.com/rzasharp79/ComfyUI--SolarFlare"
],
"install_type": "git-clone",
"description": "NODES: Qwen Image, ..."
},
{
"author": "shinich39",
"title": "comfyui-no-one-above-me [REMOVED]",
"reference": "https://github.com/shinich39/comfyui-no-one-above-me",
"files": [
"https://github.com/shinich39/comfyui-no-one-above-me"
],
"install_type": "git-clone",
"description": "Fix node to top."
},
{
"author": "octapus8085",
"title": "OpenAI-comfyui-O [REMOVED]",
"reference": "https://github.com/Spicely/Comfyui-File-Utils",
"files": [
"https://github.com/Spicely/Comfyui-File-Utils"
],
"install_type": "git-clone",
"description": "This plugin provides multiple file-handling and utility nodes for ComfyUI, including: image saving, audio saving, video saving, video composition, audio-to-subtitle conversion, and random number generation nodes. These nodes not only process files but also return their absolute file paths.\nNOTE: The files in the repo are not organized.[w/This nodepack contains a node that has a vulnerability allowing write to arbitrary file paths.]"
},
{
"author": "yemanou",
"title": "NABA Image (Gemini REST) Node [REMOVED]",
"reference": "https://github.com/yemanou/ComfyUI-NABA",
"files": [
"https://github.com/yemanou/ComfyUI-NABA"
],
"install_type": "git-clone",
"description": "Simplified Gemini 2.5 Flash Image Preview node for ComfyUI. REST-only for stability, two optional reference images, padded aspect ratio resizing (no stretching), and basic sampling controls. All extra debug layers, SDK path, multi-seed, and legacy compatibility code removed to avoid crashes."
},
{
"author": "comrender",
"title": "ComfyUI-Nano-Banana-Resizer [REMOVED]",
"reference": "https://github.com/comrender/ComfyUI-Nano-Banana-Resizer",
"files": [
"https://github.com/comrender/ComfyUI-Nano-Banana-Resizer"
],
"install_type": "git-clone",
"description": "A ComfyUI custom node that automatically calculates optimal output dimensions for Google's Nano Banana image editing model, supporting 22 aspect ratio buckets and ensuring pixel-perfect outputs without shifting or cropping."
},
{
"author": "comrender",
"title": "ComfyUI-edge-match-checker [REMOVED]",
"reference": "https://github.com/comrender/ComfyUI-edge-match-checker",
"files": [
"https://github.com/comrender/ComfyUI-edge-match-checker"
],
"install_type": "git-clone",
"description": "Node comparing two image masks or images with adjustable overlap threshold (default 95%) for detecting minor shifts and mismatches in proportions, suitable for automated post-processing validation. (Description by CC)"
},
{
"author": "comrender",
"title": "ComfyUI-gpt5_image_text [REMOVED]",
"reference": "https://github.com/comrender/ComfyUI-gpt5_image_text",
"files": [
"https://github.com/comrender/ComfyUI-gpt5_image_text"
],
"install_type": "git-clone",
"description": "A ComfyUI custom node for vision + text analysis using GPT-5 and GPT-4o with direct API key input, system prompt, temperature, max tokens, and multi-image support."
},
{
"author": "PozzettiAndrea",
"title": "ComfyUI-CameraAnalysis [REMOVED]",
"reference": "https://github.com/PozzettiAndrea/ComfyUI-CameraAnalysis",
"files": [
"https://github.com/PozzettiAndrea/ComfyUI-CameraAnalysis"
],
"install_type": "git-clone",
"description": "Extracts camera intrinsic parameters from image EXIF data."
},
{
"author": "fuzr0dah",
"title": "comfyui-sceneassembly [REMOVED]",
"reference": "https://github.com/fuzr0dah/comfyui-sceneassembly",
"files": [
"https://github.com/fuzr0dah/comfyui-sceneassembly"
],
"install_type": "git-clone",
"description": "A bunch of nodes I created that I also find useful."
},
{
"author": "rslosch",
"title": "ComfyUI-EZ_Prompts [REMOVED]",
"reference": "https://github.com/rslosch/ComfyUI-EZ_Prompts",
"files": [
"https://github.com/rslosch/ComfyUI-EZ_Prompts"
],
"install_type": "git-clone",
"description": "A ComfyUI custom node extension that provides easy-to-use prompt templates and wildcards for AI image generation."
},
{
"author": "hvppycoding",
"title": "hvppyflow [REMOVED]",
"reference": "https://github.com/hvppycoding/hvppyflow",
"files": [
"https://github.com/hvppycoding/hvppyflow"
],
"install_type": "git-clone",
"description": "ComfyUI nodes for Automated Workflow"
},
{
"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 Googles 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]",
@ -1066,16 +1557,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

View File

@ -85,7 +85,15 @@ cm_global.register_api('cm.is_import_failed_extension', is_import_failed_extensi
comfyui_manager_path = os.path.abspath(os.path.dirname(__file__))
custom_nodes_base_path = folder_paths.get_folder_paths('custom_nodes')[0]
manager_files_path = os.path.abspath(os.path.join(folder_paths.get_user_directory(), 'default', 'ComfyUI-Manager'))
# Check for System User API availability (PR #10966)
_has_system_user_api = hasattr(folder_paths, 'get_system_user_directory')
if _has_system_user_api:
manager_files_path = os.path.abspath(os.path.join(folder_paths.get_user_directory(), '__manager'))
else:
manager_files_path = os.path.abspath(os.path.join(folder_paths.get_user_directory(), 'default', 'ComfyUI-Manager'))
manager_pip_overrides_path = os.path.join(manager_files_path, "pip_overrides.json")
manager_pip_blacklist_path = os.path.join(manager_files_path, "pip_blacklist.list")
restore_snapshot_path = os.path.join(manager_files_path, "startup-scripts", "restore-snapshot.json")
@ -516,7 +524,8 @@ check_bypass_ssl()
# Perform install
processed_install = set()
script_list_path = os.path.join(folder_paths.user_directory, "default", "ComfyUI-Manager", "startup-scripts", "install-scripts.txt")
# Use manager_files_path for consistency (fixes path inconsistency bug)
script_list_path = os.path.join(manager_files_path, "startup-scripts", "install-scripts.txt")
pip_fixer = manager_util.PIPFixer(manager_util.get_installed_packages(), comfy_path, manager_files_path)
@ -793,7 +802,11 @@ def execute_startup_script():
# Check if script_list_path exists
if os.path.exists(script_list_path):
# Block startup-scripts on old ComfyUI (security measure)
if not _has_system_user_api:
if os.path.exists(script_list_path):
print("[ComfyUI-Manager] Startup scripts blocked on old ComfyUI version.")
elif os.path.exists(script_list_path):
execute_startup_script()

View File

@ -1,7 +1,7 @@
[project]
name = "comfyui-manager"
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
version = "3.37"
version = "3.38.3"
license = { file = "LICENSE.txt" }
dependencies = ["GitPython", "PyGithub", "matrix-nio", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions", "toml", "uv", "chardet"]

1014
scanner.py

File diff suppressed because it is too large Load Diff