Compare commits

...

19 Commits

Author SHA1 Message Date
Juggernaut
8b2541fe0f
Merge 2757728935 into 8d5c12037f 2026-05-02 17:47:50 +05:30
Dr.Lt.Data
8d5c12037f fix(custom-node-list): place DemonAlone-StyleSelector entry next to existing DemonAlone author block
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
2026-05-01 05:01:14 +09:00
Dr.Lt.Data
d370403e2d
Merge pull request #2827 from DemonAlone/Styler
Add DemonAlone-StyleSelector-ComfyUI  to custom-node-list.json
2026-05-01 05:00:39 +09:00
Dr.Lt.Data
e67e35795e fix(custom-node-list): place JH-PixelPro entry after last git-clone block 2026-05-01 05:00:29 +09:00
Dr.Lt.Data
ccf6d98457
Merge pull request #2809 from jetthuangai/add-comfyui-jh-pixelpro
Add ComfyUI-JH-PixelPro
2026-05-01 04:59:51 +09:00
Dr.Lt.Data
113324728e fix(custom-node-list): place Emiewn-Nodes entry after last git-clone block 2026-05-01 04:59:31 +09:00
Dr.Lt.Data
f2a3d39e26
Merge pull request #2805 from emiewnn/emiewnnodes
Add ComfyUI-Emiewn-Nodes
2026-05-01 04:58:21 +09:00
Dr.Lt.Data
ec72d983ad update DB 2026-05-01 04:45:57 +09:00
Dr.Lt.Data
a3aabfd72c
Merge pull request #2811 from Kyreo/main
Add ComfyUI-CharacterPromptBuffer by Kyreo
2026-05-01 04:42:19 +09:00
Dr.Lt.Data
03272b1f70 update DB
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2026-04-30 02:24:55 +09:00
DemonAlone
abf9c654b3
AddDemonAlone-StyleSelector-ComfyUI
to custom-node-list.json
2026-04-24 16:24:32 +03:00
Kyreo
bbc223a76c Add ComfyUI-CharacterPromptBuffer by Kyreo 2026-04-19 19:35:02 +02:00
Kyreo
aba857a350 Revert "Add ComfyUI-CharacterPromptBuffer"
This reverts commit 74c2518894.
2026-04-19 19:31:16 +02:00
Kyreo
74c2518894 Add ComfyUI-CharacterPromptBuffer 2026-04-19 19:30:37 +02:00
jetthuangai
98e0098ddd
Add ComfyUI-JH-PixelPro 2026-04-18 13:10:08 +07:00
emiewnn
ed56212fa0
Add ComfyUI-Emiewn-Nodes 2026-04-17 02:28:20 +02:00
Juggernaut
2757728935
Merge branch 'Comfy-Org:main' into main 2026-02-09 16:53:01 +05:30
Juggernaut
bb46126fbd
Merge branch 'Comfy-Org:main' into main 2026-02-06 12:31:48 +05:30
ashish
af1c698117 dependency analysis 2026-01-18 16:54:22 +05:30
8 changed files with 6856 additions and 4941 deletions

View File

@ -1705,6 +1705,17 @@
"install_type": "git-clone",
"description": "15 productivity nodes: Kraken Unbound Prompt (vision-enabled prompt builder with Qwen2-VL), WAN Prompt Splitter (cinematic styling), Ollama Prompt Chat (LLM enhancement), LoRA Loader with CivitAI trigger fetching, Dual CLIP Loader (Flux/SD3/SDXL), smart KSampler (AMP handling for WAN/Flow/FP8), Empty Latent with aspect presets, Upscale & Tile Calculator for Ultimate SD Upscale, Resolution Helper, Image Processor, WAN Helper, and more."
},
{
"author": "Kyreo",
"title": "ComfyUI-CharacterPromptBuffer",
"id": "comfyui-characterpromptbuffer",
"reference": "https://github.com/Kyreo/ComfyUI-CharacterPromptBuffer",
"files": [
"https://github.com/Kyreo/ComfyUI-CharacterPromptBuffer"
],
"install_type": "git-clone",
"description": "Nodes for generating multiple character prompt variations in a single queue run. Includes Character Prompt Manager and Variation Buffer."
},
{
"author": "Gourieff",
"title": "ComfyUI-FutureWarningIgnore",
@ -13943,6 +13954,16 @@
"install_type": "git-clone",
"description": "A Matchering audio mastering/matching node for ComfyUI."
},
{
"author": "marduk191",
"title": "comfyui-nucleus",
"reference": "https://github.com/marduk191/comfyui-nucleus",
"files": [
"https://github.com/marduk191/comfyui-nucleus"
],
"install_type": "git-clone",
"description": "Nucleus Image (MoE diffusion) support for ComfyUI — backport of PR #13471"
},
{
"author": "haohaocreates",
"title": "ComfyUI-HH-Image-Selector",
@ -30004,6 +30025,16 @@
"install_type": "git-clone",
"description": "ComfyUI nodes for FLUX.2 Klein conditioning: region-aware text enhancement, sectioned prompt encoding, and corrected reference-latent mixing with multi-reference support."
},
{
"author": "xmarre",
"title": "ComfyUI-DiffAid-Patches",
"reference": "https://github.com/xmarre/ComfyUI-DiffAid-Patches",
"files": [
"https://github.com/xmarre/ComfyUI-DiffAid-Patches"
],
"install_type": "git-clone",
"description": "A ComfyUI custom node pack implementing Diff-Aid-inspired inference-time text-conditioning patches for Flux and SDXL models."
},
{
"author": "Pigidiy",
"title": "ComfyUI-LikeSpiderAI-UI",
@ -42354,6 +42385,16 @@
"install_type": "git-clone",
"description": "A collection of nodes that provide dynamic dropdown selectors for Samplers, Schedulers, Checkpoints, and Diffusion Models, outputting a comma-separated string for use in XY plots."
},
{
"author": "DemonAlone",
"title": "DemonAlone-StyleSelector-ComfyUI",
"reference": "https://github.com/DemonAlone/DemonAlone-StyleSelector-ComfyUI",
"files": [
"https://github.com/DemonAlone/DemonAlone-StyleSelector-ComfyUI"
],
"install_type": "git-clone",
"description": "Prompt Style Selector with Preview, Multiple Selecting, Search and Local Base."
},
{
"author": "tabisheva",
"title": "comfyui-segs-profile",
@ -45534,6 +45575,16 @@
"install_type": "git-clone",
"description": "Fork of ComfyUI-Inpaint-CropAndStitch adapted for Nano Banana 2. Adds NB2 Mask Generator, exact-resolution cropping and feathered alpha compositing in the stitch step."
},
{
"author": "amortegui84",
"title": "Tile Upscale NB2",
"reference": "https://github.com/amortegui84/comfyui-tile-upscale-nb2",
"files": [
"https://github.com/amortegui84/comfyui-tile-upscale-nb2"
],
"install_type": "git-clone",
"description": "Tile-based upscaling nodes for ComfyUI — Nano Banana 2 compatible"
},
{
"author": "hqrz",
"title": "ComfyUI Japanese Romaji Converter",
@ -46007,16 +46058,6 @@
"install_type": "git-clone",
"description": "Split a multiline prompt into up to 12 numbered STRING outputs using a user-defined delimiter. Useful for multi-segment video workflows."
},
{
"author": "Kyreo",
"title": "comfyui-characterpromptbuffer",
"reference": "https://github.com/Kyreo/ComfyUI-CharacterPromptBuffer",
"files": [
"https://github.com/Kyreo/ComfyUI-CharacterPromptBuffer"
],
"install_type": "git-clone",
"description": "ComfyUI custom nodes for generating character prompt variations as batch"
},
{
"author": "Phykrex",
"title": "comfyui-momo-nodes",
@ -46047,6 +46088,146 @@
"install_type": "git-clone",
"description": "Personal ComfyUI custom nodes."
},
{
"author": "wos-ai-studio",
"title": "ComfyUI-Title-Memo",
"reference": "https://github.com/xujianjian2004/ComfyUI-Title-Memo",
"files": [
"https://github.com/xujianjian2004/ComfyUI-Title-Memo"
],
"install_type": "git-clone",
"description": "Add title, comment and memo functions to nodes, which support custom styles and automatic word wrapping, compatible with Nodes 2.0."
},
{
"author": "ussaaron",
"title": "FrameFuse",
"reference": "https://github.com/headline-design/comfyui-framefuse",
"files": [
"https://github.com/headline-design/comfyui-framefuse"
],
"install_type": "git-clone",
"description": "ComfyUI nodes for stitching a still frame onto the start or end of an IMAGE video batch and trimming extra tail frames with optional audio sync alignment."
},
{
"author": "takkun",
"title": "ComfyUI-StepByStep-Sampler",
"reference": "https://github.com/TakkunRed/ComfyUI-StepByStep-Sampler",
"files": [
"https://github.com/TakkunRed/ComfyUI-StepByStep-Sampler"
],
"install_type": "git-clone",
"description": "ComfyUI StepByStep Sampler is a plugin for ComfyUI that provides a step-by-step sampling method for image generation. It allows users to generate images in a more controlled and iterative manner, making it easier to achieve desired results."
},
{
"author": "serhiiyashyn-sf",
"title": "Face-Aligned Center",
"reference": "https://github.com/serhiiyashyn-sf/comfyui-face-aligned-center",
"files": [
"https://github.com/serhiiyashyn-sf/comfyui-face-aligned-center"
],
"install_type": "git-clone",
"description": "Batch-aware character centering for ComfyUI. Given a character sheet (multiple angles), scales every image so the face ends up at the same size and canvas position — including back-view angles, via a silhouette fallback tied to the batch's face scale. Includes a Fine-Tune node for per-image zoom/nudge with a live canvas preview, and an Anime Face Detect node for crop+mask using lbpcascade_animeface."
},
{
"author": "newgrit1004",
"title": "Qwen3 Triton TTS",
"reference": "https://github.com/newgrit1004/ComfyUI-Qwen3-TTS-Triton",
"files": [
"https://github.com/newgrit1004/ComfyUI-Qwen3-TTS-Triton"
],
"install_type": "git-clone",
"description": "ComfyUI node wrapping qwen3-tts-triton for 7-mode Qwen3-TTS inference (Triton kernel fusion + TurboQuant KV cache)"
},
{
"author": "mahilkr",
"title": "HunyuanWorld 3D World Generation",
"reference": "https://github.com/krmahil/comfyui-hunyuan-world",
"files": [
"https://github.com/krmahil/comfyui-hunyuan-world"
],
"install_type": "git-clone",
"description": "ComfyUI custom nodes for immersive 3D world generation using Tencent HunyuanWorld 1.0"
},
{
"author": "machinedelusions",
"title": "ComfyUI-FL-LTXTools",
"reference": "https://github.com/filliptm/ComfyUI-FL-LTXTools",
"files": [
"https://github.com/filliptm/ComfyUI-FL-LTXTools"
],
"install_type": "git-clone",
"description": "Experimental tools and motion controls for LTX-Video in ComfyUI"
},
{
"author": "intelliprompt",
"title": "comfy-intelliprompt",
"reference": "https://github.com/galpt/comfy-intelliPrompt",
"files": [
"https://github.com/galpt/comfy-intelliPrompt"
],
"install_type": "git-clone",
"description": "intelliPrompt - An intelligent prompt optimizer for ComfyUI that fixes typos, balances parentheses, and enhances prompts"
},
{
"author": "enviral-design",
"title": "Enviral Design Node Pack",
"reference": "https://github.com/EnviralDesign/comfyUI-enviral-design-node-pack",
"files": [
"https://github.com/EnviralDesign/comfyUI-enviral-design-node-pack"
],
"install_type": "git-clone",
"description": "Small, dependency-light ComfyUI utility nodes from Enviral Design."
},
{
"author": "eniewold",
"title": "Subworkflow (reusable workflows)",
"reference": "https://github.com/eniewold/ComfyUI-Subworkflow",
"files": [
"https://github.com/eniewold/ComfyUI-Subworkflow"
],
"install_type": "git-clone",
"description": "Use ComfyUI workflows as reusable subworkflows via Subworkflow Input, Subworkflow Output, and Subworkflow nodes"
},
{
"author": "dorpxam",
"title": "LTX-2 Microscope",
"reference": "https://github.com/dorpxam/ComfyUI-LTX2-Microscope",
"files": [
"https://github.com/dorpxam/ComfyUI-LTX2-Microscope"
],
"install_type": "git-clone",
"description": "48-Layers Latent Previewer for Lightrick's LTX-2 model."
},
{
"author": "dailydoseofaiart",
"title": "ComfyUI-FPSFrameDrop",
"reference": "https://github.com/dailydoseofaiart/ComfyUI-FPSFrameDrop",
"files": [
"https://github.com/dailydoseofaiart/ComfyUI-FPSFrameDrop"
],
"install_type": "git-clone",
"description": "A node to drop frames from the output images to force the video to a lower FPS at the same playback speed."
},
{
"author": "Emiewn",
"title": "ComfyUI-Emiewn-Nodes",
"reference": "https://github.com/emiewnn/ComfyUI-Emiewn-Nodes",
"files": [
"https://github.com/emiewnn/ComfyUI-Emiewn-Nodes"
],
"install_type": "git-clone",
"description": "Custom nodes for ComfyUI: Drag & drop image paste, interactive UI crop, WAN I2V bucket resolution, and GIMM-VFI frame interpolation."
},
{
"author": "jetthuangai",
"title": "ComfyUI-JH-PixelPro",
"reference": "https://github.com/jetthuangai/ComfyUI-JH-PixelPro",
"files": [
"https://github.com/jetthuangai/ComfyUI-JH-PixelPro"
],
"install_type": "git-clone",
"description": "GPU-powered pro-grade image suite cho retouch chân dung. v0.1.0 alpha: Frequency Separation (N-01) + Sub-Pixel Mask Refiner (N-02). Kornia core, tensor thuần không rời VRAM."
},

View File

@ -2209,13 +2209,16 @@
"AcademiaSD_Downloader",
"AcademiaSD_Gemini_Node",
"AcademiaSD_LTXVMultiFrames",
"AcademiaSD_LoopCounter",
"AcademiaSD_MultiLora",
"AcademiaSD_MultiPrompt",
"AcademiaSD_Numeric",
"AcademiaSD_Resolution",
"AcademiaSD_ResolutionDisplay",
"AcademiaSD_SaveAndSend",
"AcademiaSD_SaveCaption",
"AcademiaSD_TimeCalculator",
"AcademiaSD_VideoKeyframer",
"AcademiaVisionNode",
"IntegerBypasser",
"LoopCounterToFile",
@ -7132,6 +7135,9 @@
"BoyoPairedSaver",
"BoyoPromptInjector",
"BoyoPromptLoop",
"BoyoPromptRelayEncode",
"BoyoPromptRelayEncodeTimeline",
"BoyoPromptRelayLoraGate",
"BoyoQwenVLGrounding",
"BoyoResolutionCalc",
"BoyoSaver",
@ -7660,6 +7666,14 @@
"title_aux": "comfyui-sdnq"
}
],
"https://github.com/EnviralDesign/comfyUI-enviral-design-node-pack": [
[
"EnviralTextSplitByDelimiter"
],
{
"title_aux": "Enviral Design Node Pack"
}
],
"https://github.com/Eonizer/ComfyUI-bby-nodes": [
[
"TagFilterNode"
@ -9569,10 +9583,13 @@
"https://github.com/GoogleCloudPlatform/comfyui-google-genmedia-custom-nodes": [
[
"Gemini25FlashImage",
"Gemini31FlashImage",
"Gemini3ProImage",
"GeminiNode25",
"GeminiNode31",
"Imagen3TextToImageNode",
"Imagen4TextToImageNode",
"Imagen4UpscaleImageNode",
"Lyria2TextToMusicNode",
"Veo2GcsUriImageToVideoNode",
"Veo2ImageToVideoNode",
@ -10951,12 +10968,30 @@
],
"https://github.com/IAMCCS/IAMCCS-nodes": [
[
"IAMCCS-SuperNodes AU+IMG2VID Exec Finalize",
"IAMCCS-SuperNodes AU+IMG2VID Exec Planner",
"IAMCCS-SuperNodes AU+IMG2VID Exec Render",
"IAMCCS-SuperNodes AU+IMG2VID Exec VAE",
"IAMCCS-SuperNodes Second Stage",
"IAMCCS_AUIMG2VID_AudioTimeline",
"IAMCCS_AUIMG2VID_Continuity",
"IAMCCS_AUIMG2VID_DiskExtension",
"IAMCCS_AUIMG2VID_Finalize",
"IAMCCS_AUIMG2VID_KeyframeTimeline",
"IAMCCS_AUIMG2VID_Planner",
"IAMCCS_AUIMG2VID_ProjectTimelinePlanner",
"IAMCCS_AUIMG2VID_ReanchorLatent",
"IAMCCS_AUIMG2VID_RefreshPolicy",
"IAMCCS_AUIMG2VID_RuntimeBridge",
"IAMCCS_ApplyLoRAHooksToConditioning",
"IAMCCS_ApplyScheduledWanLoRAFromConditioning",
"IAMCCS_AudioExtender",
"IAMCCS_AudioExtensionMath",
"IAMCCS_AudioTimelineAssembler",
"IAMCCS_AudioTimelineGate",
"IAMCCS_AutoLinkArguments",
"IAMCCS_AutoLinkConverter",
"IAMCCS_BuildScheduledWanModelBank",
"IAMCCS_FluxKleinMultiGen",
"IAMCCS_GGUF_accelerator",
"IAMCCS_GetAutoLink",
@ -10966,7 +11001,19 @@
"IAMCCS_HwSupporterAny",
"IAMCCS_ImageResizeBatchSafe",
"IAMCCS_IntValueMonitor",
"IAMCCS_LTX2_AudioPromptDirector",
"IAMCCS_LTX2_BlendLatentBridge",
"IAMCCS_LTX2_CinematicLineStacker",
"IAMCCS_LTX2_CinematicMultiGenPlanner",
"IAMCCS_LTX2_CinematicPromptComposer",
"IAMCCS_LTX2_CinematicPromptRelayAdapter",
"IAMCCS_LTX2_CinematicRefLatentControl",
"IAMCCS_LTX2_CinematicShotAudioSelector",
"IAMCCS_LTX2_CinematicShotLineBuilder",
"IAMCCS_LTX2_CinematicShotPlanner",
"IAMCCS_LTX2_CinematicV2VAssetSelector",
"IAMCCS_LTX2_CinematicV2VTimelineLineBuilder",
"IAMCCS_LTX2_CinematicV2VTimelinePlanner",
"IAMCCS_LTX2_ConditionNextLatentWithPrevOverlap",
"IAMCCS_LTX2_ContextLatent",
"IAMCCS_LTX2_ControlPreprocess",
@ -11005,11 +11052,23 @@
"IAMCCS_LTX2_TimeFrameCount",
"IAMCCS_LTX2_Validator",
"IAMCCS_LatentTailSlice",
"IAMCCS_LazyAnySwitch",
"IAMCCS_LoadImagesFromDirLite",
"IAMCCS_LoadResizeSegmentFromDir",
"IAMCCS_Ltx2HelperModules_AudioTimeline",
"IAMCCS_Ltx2HelperModules_Continuity",
"IAMCCS_Ltx2HelperModules_DiskExtension",
"IAMCCS_Ltx2HelperModules_Finalize",
"IAMCCS_Ltx2HelperModules_KeyframeTimeline",
"IAMCCS_Ltx2HelperModules_Planner",
"IAMCCS_Ltx2HelperModules_ProjectTimelinePlanner",
"IAMCCS_Ltx2HelperModules_ReanchorLatent",
"IAMCCS_Ltx2HelperModules_RefreshPolicy",
"IAMCCS_Ltx2HelperModules_RuntimeBridge",
"IAMCCS_ModelWithLoRA",
"IAMCCS_ModelWithLoRA_LTX2",
"IAMCCS_ModelWithLoRA_LTX2_Staged",
"IAMCCS_ModelWithLoRA_RuntimeBridge",
"IAMCCS_MotionBridgeLoad",
"IAMCCS_MotionBridgeSave",
"IAMCCS_MotionScale",
@ -11018,17 +11077,25 @@
"IAMCCS_MoveAheadEnforcer",
"IAMCCS_MultiSwitch",
"IAMCCS_MultilinePromptSplitter8",
"IAMCCS_ProjectTimelinePlanner",
"IAMCCS_QWEN_VL_FLF",
"IAMCCS_QWEN_VL_FLF_Advanced",
"IAMCCS_QwenMultiGen",
"IAMCCS_SamplerAdvancedVersion1",
"IAMCCS_SegmentPlanFromPlanner",
"IAMCCS_SegmentPlanner",
"IAMCCS_SegmentPlannerLinked",
"IAMCCS_SegmentPlannerSettings",
"IAMCCS_SegmentSwitch",
"IAMCCS_SelectScheduledWanModelFromConditioning",
"IAMCCS_SelectScheduledWanModelPairFromConditioning",
"IAMCCS_SetAutoLink",
"IAMCCS_SourceFramesToDisk",
"IAMCCS_SourceRangeFromSegmentPlan",
"IAMCCS_StartDirToVideoLatent",
"IAMCCS_StartImagesToVideoLatent",
"IAMCCS_SupernodeBase",
"IAMCCS_SupernodeModule",
"IAMCCS_ThreeSegmentPlanner",
"IAMCCS_TwoSegmentPlanner",
"IAMCCS_VAEDecodeTiledSafe",
@ -11048,6 +11115,8 @@
"IAMCCS_WanImageMotionPro_Simple",
"IAMCCS_WanImageMotion_AdaIN",
"IAMCCS_WanIndexedPromptEncode",
"IAMCCS_WanLoRAHookSchedule",
"IAMCCS_WanLoRARuntimeBridge",
"IAMCCS_WanLoRASchedule",
"IAMCCS_WanLoRAStack",
"IAMCCS_WanLoRAStackModelIO",
@ -13894,7 +13963,10 @@
],
"https://github.com/Limbicnation/ComfyUI-PromptGenerator": [
[
"Limbicnation_NegativePrompt",
"Limbicnation_PromptCombiner",
"Limbicnation_PromptGenerator",
"Limbicnation_PromptRefiner",
"Limbicnation_StyleApplier"
],
{
@ -15804,11 +15876,13 @@
"NLConstantColor",
"NLContextDebug",
"NLEdit",
"NLFitFrame",
"NLFromModelSpace",
"NLImageInfoDebug",
"NLLTXVImgToVideoInplaceAtIndex",
"NLLinearToLog",
"NLLogToLinear",
"NLMatch",
"NLMerge",
"NLOCIOConvert",
"NLPreview",
@ -16779,9 +16853,13 @@
"CRTPostProcess",
"CRT_AddSettingsAndPrompt",
"CRT_AudioTranscript",
"CRT_AudioTranscriptPipeOut",
"CRT_DynamicPromptScheduler",
"CRT_FileBatchPromptScheduler",
"CRT_ImageLoaderCrawlBatch",
"CRT_IsolateInput",
"CRT_IsolateInputCLIPSeg",
"CRT_IsolateOutput",
"CRT_KSamplerBatch",
"CRT_KSamplerBatchAdvanced",
"CRT_LTX23AutoDownload",
@ -17418,20 +17496,39 @@
"GeomPackAddNormalsToPointCloud",
"GeomPackAlphaWrap",
"GeomPackBackdraftView",
"GeomPackBooleanBlender",
"GeomPackBooleanCGAL",
"GeomPackBoolean",
"GeomPackBoolean_BlenderExact",
"GeomPackBoolean_LibiglCGAL",
"GeomPackCheckNormals",
"GeomPackCombineMeshes",
"GeomPackCombineMeshesBatch",
"GeomPackComputeNormals",
"GeomPackConnectedComponents",
"GeomPackCreatePrimitive",
"GeomPackDecimateMesh",
"GeomPackDecimate_CGALEdgeCollapse",
"GeomPackDecimate_DecimatePro",
"GeomPackDecimate_FastSimplification",
"GeomPackDecimate_QuadricEdgeCollapse",
"GeomPackDecimate_VertexClustering",
"GeomPackDegenerateFaces",
"GeomPackDepthNormalsToMesh",
"GeomPackDetectSelfIntersections",
"GeomPackExtractLargestComponent",
"GeomPackExtractSkeleton",
"GeomPackFillHoles",
"GeomPackFillHoles_CGAL",
"GeomPackFillHoles_GPU",
"GeomPackFillHoles_IglFan",
"GeomPackFillHoles_PyMeshFix",
"GeomPackFillHoles_PyMeshLab",
"GeomPackFillHoles_Trimesh",
"GeomPackFixNormals",
"GeomPackFixNormals_IglBfs",
"GeomPackFixNormals_IglRaycast",
"GeomPackFixNormals_IglSignedDist",
"GeomPackFixNormals_IglWinding",
"GeomPackFixNormals_Trimesh",
"GeomPackFixSelfIntersectionsByPerturbation",
"GeomPackFixSelfIntersectionsByRemoval",
"GeomPackGetMeshFilename",
@ -17461,20 +17558,63 @@
"GeomPackPreviewMeshVTK",
"GeomPackPreviewMeshVTKBatch",
"GeomPackReconstructSurface",
"GeomPackReconstruct_AlphaShape",
"GeomPackReconstruct_BallPivoting",
"GeomPackReconstruct_ConvexHull",
"GeomPackReconstruct_Poisson",
"GeomPackRemesh",
"GeomPackRemeshBlender",
"GeomPackRemeshCGAL",
"GeomPackRemeshGPU",
"GeomPackRemeshSelfIntersections",
"GeomPackRemeshWithTexture",
"GeomPackRemesh_BlenderBlocks",
"GeomPackRemesh_BlenderSharp",
"GeomPackRemesh_BlenderVoxel",
"GeomPackRemesh_CGAL",
"GeomPackRemesh_GPU",
"GeomPackRemesh_GeogramAniso",
"GeomPackRemesh_GeogramSmooth",
"GeomPackRemesh_InstantMeshes",
"GeomPackRemesh_MMG",
"GeomPackRemesh_PMPAdaptive",
"GeomPackRemesh_PMPUniform",
"GeomPackRemesh_PyMeshLab",
"GeomPackRemesh_QuadWild",
"GeomPackRemesh_QuadriFlow",
"GeomPackRemoveDegenerateFaces",
"GeomPackSaveMesh",
"GeomPackSaveMeshBatch",
"GeomPackSharpenMesh",
"GeomPackSharpen_FastEffective",
"GeomPackSharpen_GuidedNormal",
"GeomPackSharpen_L0Minimize",
"GeomPackSharpen_LibiglUnsharp",
"GeomPackSharpen_NonIterative",
"GeomPackSharpen_TwoStep",
"GeomPackSharpen_UnsharpMask",
"GeomPackSkeleton_EdgeCollapse",
"GeomPackSkeleton_Teasar",
"GeomPackSkeleton_VertexClusters",
"GeomPackSkeleton_Wavefront",
"GeomPackSmoothMesh",
"GeomPackSmooth_HCLaplacian",
"GeomPackSmooth_Laplacian",
"GeomPackSmooth_Taubin",
"GeomPackSmooth_TrimeshLaplacian",
"GeomPackSmooth_TrimeshTaubin",
"GeomPackSplitByField",
"GeomPackSubsamplePointCloud",
"GeomPackTextureToGeometry",
"GeomPackTransformMesh",
"GeomPackUVUnwrap",
"GeomPackUV_BlenderCube",
"GeomPackUV_BlenderCylinder",
"GeomPackUV_BlenderSmart",
"GeomPackUV_BlenderSphere",
"GeomPackUV_CuMesh",
"GeomPackUV_LibiglARAP",
"GeomPackUV_LibiglHarmonic",
"GeomPackUV_LibiglLSCM",
"GeomPackUV_Xatlas",
"GeomPackVisualizeNormalField",
"RefineMesh",
"ScrambleIntField"
@ -18008,6 +18148,7 @@
"RSCropImage",
"RSInsertCropImage",
"RSOutpaint",
"RSPrompts",
"RSSaveImage",
"RS_Last_Frame",
"RS_Saturation",
@ -22207,6 +22348,17 @@
"title_aux": "Fens-Simple-Nodes"
}
],
"https://github.com/TakkunRed/ComfyUI-StepByStep-Sampler": [
[
"StepByStepGridSampler",
"StepByStepSampler",
"StepStepComparer",
"StepStepPlayer"
],
{
"title_aux": "ComfyUI-StepByStep-Sampler"
}
],
"https://github.com/TakkunRed/comfyui_checkpoint_preset_manager": [
[
"CheckpointPresetNode"
@ -24046,7 +24198,14 @@
"FD_SeedreamImage",
"FD_Upload",
"FD_ZImageTurboGenImage",
"FD_imgToText_Doubao"
"FD_imgToText_Doubao",
"GPTImageEdit",
"MaoziEcommercePromptGenerator",
"MaoziPromptListSelector",
"NodeToggleByID",
"ZhiYiImageTextNode",
"ZhiYiImageToImageNode",
"ZhiYiTextGenNode"
],
{
"title_aux": "Comfyui_Fd_Nodes"
@ -26355,9 +26514,10 @@
],
"https://github.com/akawana/ComfyUI-Folded-Prompts": [
[
"ExecutionBlockerBreaker",
"FPFoldedPrompts",
"FPTab",
"FPTabbedTextArea",
"FPTabedTextPassthrough",
"FPTextAreaPlus",
"FPTextCleanAndSplitt"
],
@ -27170,12 +27330,33 @@
"InpaintCropNB2",
"InpaintStitchNB2",
"NB2AddAlpha",
"NanoBanana2MaskGen"
"NB2Florence2RegionSelector",
"NB2OpenAIImageEdit",
"NB2SmartRegionMask",
"NanoBanana2MaskGen",
"SmartMaskCrop",
"SmartMaskStitch"
],
{
"title_aux": "ComfyUI-Inpaint-CropStitch-NB2"
}
],
"https://github.com/amortegui84/comfyui-tile-upscale-nb2": [
[
"FlorenceMaskAlign",
"MaskBBoxCrop",
"TileCollect",
"TileCrop",
"TileCropNB2",
"TileExtract",
"TileInfo",
"TileStitch",
"TileStitchNB2"
],
{
"title_aux": "Tile Upscale NB2"
}
],
"https://github.com/amtarr/ComfyUI-TextureAlchemy": [
[
"AOApproximator",
@ -29314,6 +29495,7 @@
"https://github.com/bollerdominik/ComfyUI-load-lora-from-url": [
[
"AssertNotBlack",
"BytePlusVideoGeneration",
"CutImageByMask",
"GeminiImage2GenAI",
"ImageResize+",
@ -30084,7 +30266,6 @@
"Flux2KleinKSamplerExperimental",
"Flux2KleinMaskRefController",
"Flux2KleinRefLatentController",
"Flux2KleinRefLatentWeight",
"Flux2KleinSectionedEncoder",
"Flux2KleinTextEnhancer",
"Flux2KleinTextRefBalance",
@ -30151,6 +30332,7 @@
"AD_frame_replace",
"AD_keyframe_trend_preview",
"AD_latent_history",
"AD_media_trim_visual",
"AD_pingpong_vedio",
"AD_sch_IPA",
"AD_sch_image_merge",
@ -30159,8 +30341,11 @@
"AD_sch_prompt_stack",
"AD_sch_value",
"AD_video_merge",
"AI_DoubaoWebPreview",
"AI_GLM_image",
"AI_GLM_text",
"AI_Gemini3_ImageEdit",
"AI_Gemini3_Img2T",
"AI_ModelScopeImageEdit",
"AI_ModelScopeT2I",
"AI_ModelScope_image",
@ -30183,6 +30368,7 @@
"Coordinate_Index2Text",
"Coordinate_MarkRender",
"Coordinate_SplitIndex",
"Coordinate_create_mask",
"Coordinate_fromImage",
"Coordinate_fromMask",
"Coordinate_loadImage",
@ -30198,10 +30384,12 @@
"Easy_QwenEdit2509",
"IO_EasyMark",
"IO_ImageSaveOverwrite",
"IO_LoadAudioBatch",
"IO_LoadImgBatch",
"IO_LoadImgList",
"IO_LoadShotBatch",
"IO_LoadTextBatch",
"IO_LoadVideoBatch",
"IO_PathProcessor",
"IO_RegexPreset",
"IO_ShotCreate",
@ -30302,6 +30490,7 @@
"Stack_pre_Mark2",
"Stack_sample_data",
"Stack_text",
"UniversalAPI",
"basicIn_Boolean",
"basicIn_Remap_slide",
"basicIn_Sampler",
@ -30480,10 +30669,10 @@
"text_StrMatrix",
"text_converter",
"text_filter",
"text_interPrompt",
"text_list_combine",
"text_loadText",
"text_modifier",
"text_mulAngle",
"text_mul_Join",
"text_mul_Split",
"text_saveText",
@ -32817,6 +33006,10 @@
"GrokVideoNode",
"GrokVideoReferenceNode",
"GrowMask",
"HappyHorseImageToVideoApi",
"HappyHorseReferenceVideoApi",
"HappyHorseTextToVideoApi",
"HappyHorseVideoEditApi",
"HitPawGeneralImageEnhance",
"HitPawVideoEnhance",
"Hunyuan3Dv2Conditioning",
@ -34263,6 +34456,14 @@
"title_aux": "SDXL Auto Prompter"
}
],
"https://github.com/dailydoseofaiart/ComfyUI-FPSFrameDrop": [
[
"VHSForceFPSKeepSpeed"
],
{
"title_aux": "ComfyUI-FPSFrameDrop"
}
],
"https://github.com/danTheMonk/comfyui-int-and-float": [
[
"FloatToInt",
@ -35230,6 +35431,14 @@
"title_aux": "ComfyUI-LTXVideo-Extra"
}
],
"https://github.com/dorpxam/ComfyUI-LTX2-Microscope": [
[
"LTX2Microscope"
],
{
"title_aux": "LTX-2 Microscope"
}
],
"https://github.com/dothings/comfyui_placeholder_prompting": [
[
"PlaceholderPrompting"
@ -36046,6 +36255,17 @@
"title_aux": "ComfyUI-Image-Cipher"
}
],
"https://github.com/eniewold/ComfyUI-Subworkflow": [
[
"BaseSubworkflow",
"SWF_SubworkflowInput",
"SWF_SubworkflowModifier",
"SWF_SubworkflowOutput"
],
{
"title_aux": "Subworkflow (reusable workflows)"
}
],
"https://github.com/envy-ai/ComfyUI-ConDelta": [
[
"ApplyConDelta",
@ -36894,6 +37114,14 @@
"title_aux": "ComfyUI-FL-DiffVSR"
}
],
"https://github.com/filliptm/ComfyUI-FL-LTXTools": [
[
"FL_LTX_MotionBoost"
],
{
"title_aux": "ComfyUI-FL-LTXTools"
}
],
"https://github.com/filliptm/ComfyUI_FL-ClearVoice": [
[
"FL_ClearVoice_ModelLoader",
@ -37003,6 +37231,7 @@
"FL_ColorPicker",
"FL_CreateShapeImageOnPath",
"FL_Dalle3",
"FL_DepthBlur",
"FL_DirectoryCrawl",
"FL_Dither",
"FL_FILM",
@ -37849,6 +38078,15 @@
"title_aux": "ComfyUI-String-Similarity"
}
],
"https://github.com/galpt/comfy-intelliPrompt": [
[
"IntelliPromptResolutionPresetLatent",
"intelliPrompt"
],
{
"title_aux": "comfy-intelliprompt"
}
],
"https://github.com/game4d/ComfyUI-BDsInfiniteYou": [
[
"InfiniteYou_Image",
@ -39189,6 +39427,15 @@
"title_aux": "ComfyUI-ReplenishNodes"
}
],
"https://github.com/headline-design/comfyui-framefuse": [
[
"FrameFuse",
"FrameFuseTrimEnd"
],
{
"title_aux": "FrameFuse"
}
],
"https://github.com/heheok/comfyui_wan2.1_vace_infinite_helpers": [
[
"CyclicCharacterAndBackgroundPrompt",
@ -40413,7 +40660,7 @@
"https://github.com/ialhabbal/OcclusionMask": [
[
"BatchLoadImages",
"ImageOcclusion"
"OcclusionMask"
],
{
"title_aux": "OcclusionMask"
@ -40692,6 +40939,7 @@
[
"Light-Tool: AddBackground",
"Light-Tool: AddBackgroundV2",
"Light-Tool: AspectRatioPadder",
"Light-Tool: BoundingBoxCropping",
"Light-Tool: Calculate",
"Light-Tool: ConvertNumType",
@ -44836,6 +45084,18 @@
"title_aux": "Hollow Preserve"
}
],
"https://github.com/krmahil/comfyui-hunyuan-world": [
[
"HYWorldFullPipeline",
"HYWorldImage2Pano",
"HYWorldSceneGen",
"HYWorldText2Pano",
"HYWorldUnloadModels"
],
{
"title_aux": "HunyuanWorld 3D World Generation"
}
],
"https://github.com/kukuo6666/ComfyUI-Equirect": [
[
"CubemapToEquirect",
@ -44997,7 +45257,8 @@
"Leon_StableDiffusion_35_API_Node",
"Leon_StableDiffusion_3_Ultra_API_Node",
"Leon_StableDiffusion_XL_API_Node",
"Leon_String_Combine_Node"
"Leon_String_Combine_Node",
"Leon_Yellow_Tint_Cleaner_Node"
],
{
"nodename_pattern": "^\ud83e\udd16 Leon",
@ -48146,6 +48407,14 @@
"title_aux": "marduk191 workflow settings"
}
],
"https://github.com/marduk191/comfyui-nucleus": [
[
"NucleusCLIPLoader"
],
{
"title_aux": "comfyui-nucleus"
}
],
"https://github.com/marduk191/comfyui_qwen_runninghub": [
[
"RunningHubImageEnhancer",
@ -48471,6 +48740,7 @@
"mrmth_ModelMathNode",
"mrmth_NoiseMathNode",
"mrmth_ScriptInput",
"mrmth_StackUnBatcher",
"mrmth_VAEMathNode",
"mrmth_VideoMathNode",
"mrmth_ag_AudioMathNode",
@ -48894,6 +49164,8 @@
"ExecutionGateControl",
"FrameAccumulator",
"FrameContextFit",
"FreeVRAMIfLoaded",
"FreeVRAMUnlessLoaded",
"ImageExists",
"ImageFallback",
"ImageModeRouter",
@ -50221,6 +50493,15 @@
"title_aux": "ComfyUI-StyleShot"
}
],
"https://github.com/newgrit1004/ComfyUI-Qwen3-TTS-Triton": [
[
"Qwen3TTSCustomVoice",
"Qwen3TTSVoiceClone"
],
{
"title_aux": "Qwen3 Triton TTS"
}
],
"https://github.com/ngosset/ComfyUI-ImageSimilarity": [
[
"Image Similarity"
@ -55462,6 +55743,16 @@
"title_aux": "ComfyUI_Nimbus-Pack"
}
],
"https://github.com/serhiiyashyn-sf/comfyui-face-aligned-center": [
[
"AnimeFaceDetect",
"FaceAlignedCenter",
"FaceAlignedFineTune"
],
{
"title_aux": "Face-Aligned Center"
}
],
"https://github.com/serious-factory/ComfyUI-MultiTalkPromptSchedule": [
[
"MultiTalkPromptSchedule"
@ -59816,6 +60107,7 @@
],
"https://github.com/ussoewwin/ComfyUI-NunchakuFluxLoraStacker": [
[
"ColorFilter",
"FastGroupsBypasserV2",
"FluxLoraMultiLoader",
"LoadImageUssoewwin",
@ -60364,6 +60656,7 @@
"VRGDG_CreateFinalVideo",
"VRGDG_CreateFinalVideo_SRT",
"VRGDG_CreateSilentAudio",
"VRGDG_CyclingTextPicker",
"VRGDG_DisplayIndex",
"VRGDG_DurationIndexFloat",
"VRGDG_Extract_Frame_Number",
@ -60411,6 +60704,8 @@
"VRGDG_LoadTextAdvanced",
"VRGDG_LoadVideos",
"VRGDG_LocalLLM",
"VRGDG_LyricSegmentDurationMerger",
"VRGDG_LyricSegmentJsonFixer",
"VRGDG_LyricsEmotionMerger",
"VRGDG_MakeLUT",
"VRGDG_ManualLyricsExtractor",
@ -60428,6 +60723,8 @@
"VRGDG_PadVideoWithLastFrame",
"VRGDG_PostRunIndexStepper",
"VRGDG_PromptCreatorUI",
"VRGDG_PromptCreatorUI_V2",
"VRGDG_PromptMapJsonFixer",
"VRGDG_PromptSpitterWithIndex",
"VRGDG_PromptSplitter",
"VRGDG_PromptSplitter2",
@ -60459,6 +60756,7 @@
"VRGDG_SpeedCharacterLoraTraining",
"VRGDG_SplitPrompt_T2I_I2V",
"VRGDG_StoryBoardCreator",
"VRGDG_StoryGroupJsonFixer",
"VRGDG_String2Json",
"VRGDG_StringConcat",
"VRGDG_SuperGemmaGGUFChat",
@ -61805,6 +62103,15 @@
"title_aux": "ComfyUI-AutoGuidance"
}
],
"https://github.com/xmarre/ComfyUI-DiffAid-Patches": [
[
"Flux2DiffAidSparsePatch",
"SDXLDiffAidCrossAttentionPatch"
],
{
"title_aux": "ComfyUI-DiffAid-Patches"
}
],
"https://github.com/xmarre/ComfyUI-Flux2Klein-Conditioning-Toolkit": [
[
"Flux2KleinConditioningEnhancer",
@ -62017,6 +62324,14 @@
"title_aux": "ComfyUI_Camera"
}
],
"https://github.com/xujianjian2004/ComfyUI-Title-Memo": [
[
"Title_Memo"
],
{
"title_aux": "ComfyUI-Title-Memo"
}
],
"https://github.com/xuxiao305/ComfyUI-ImageBatchUtils": [
[
"ImageBatchCount",
@ -62436,6 +62751,7 @@
"ycCanvasBBox",
"ycCanvasBBoxMask",
"ycImageCrop",
"ycImageCropBatchApply",
"ycImageCropInteractive",
"ycimagebrushmask"
],

File diff suppressed because it is too large Load Diff

View File

@ -921,7 +921,7 @@ class UnifiedManager:
except:
return version.parse("0.0.0")
def execute_install_script(self, url, repo_path, instant_execution=False, lazy_mode=False, no_deps=False):
def execute_install_script(self, url, repo_path, instant_execution=False, lazy_mode=False, no_deps=False, selected_dependencies=None):
install_script_path = os.path.join(repo_path, "install.py")
requirements_path = os.path.join(repo_path, "requirements.txt")
@ -933,8 +933,19 @@ class UnifiedManager:
if os.path.exists(requirements_path) and not no_deps:
print("Install: pip packages")
pip_fixer = manager_util.PIPFixer(manager_util.get_installed_packages(), comfy_path, manager_files_path)
# Create a set of selected dependency lines for quick lookup
selected_lines = set()
if selected_dependencies:
for dep in selected_dependencies:
selected_lines.add(dep.get('line', '').strip())
lines = manager_util.robust_readlines(requirements_path)
for line in lines:
# Skip if selected_dependencies is provided and this line is not in the selected list
if selected_dependencies is not None and line.strip() not in selected_lines:
continue
package_name = remap_pip_package(line.strip())
if package_name and not package_name.startswith('#') and package_name not in self.processed_install:
self.processed_install.add(package_name)
@ -1342,7 +1353,7 @@ class UnifiedManager:
return result
def repo_install(self, url: str, repo_path: str, instant_execution=False, no_deps=False, return_postinstall=False):
def repo_install(self, url: str, repo_path: str, instant_execution=False, no_deps=False, return_postinstall=False, selected_dependencies=None):
result = ManagedResult('install-git')
result.append(url)
@ -1369,7 +1380,7 @@ class UnifiedManager:
repo.close()
def postinstall():
return self.execute_install_script(url, repo_path, instant_execution=instant_execution, no_deps=no_deps)
return self.execute_install_script(url, repo_path, instant_execution=instant_execution, no_deps=no_deps, selected_dependencies=selected_dependencies)
if return_postinstall:
return result.with_postinstall(postinstall)
@ -1468,7 +1479,7 @@ class UnifiedManager:
else:
return self.cnr_switch_version(node_id, instant_execution=instant_execution, no_deps=no_deps, return_postinstall=return_postinstall).with_ver('cnr')
async def install_by_id(self, node_id: str, version_spec=None, channel=None, mode=None, instant_execution=False, no_deps=False, return_postinstall=False):
async def install_by_id(self, node_id: str, version_spec=None, channel=None, mode=None, instant_execution=False, no_deps=False, return_postinstall=False, selected_dependencies=None):
"""
priority if version_spec == None
1. CNR latest
@ -1519,7 +1530,7 @@ class UnifiedManager:
self.unified_disable(node_id, False)
to_path = os.path.abspath(os.path.join(get_default_custom_nodes_path(), node_id))
res = self.repo_install(repo_url, to_path, instant_execution=instant_execution, no_deps=no_deps, return_postinstall=return_postinstall)
res = self.repo_install(repo_url, to_path, instant_execution=instant_execution, no_deps=no_deps, return_postinstall=return_postinstall, selected_dependencies=selected_dependencies)
if res.result:
if version_spec == 'unknown':
self.unknown_active_nodes[node_id] = repo_url, to_path
@ -1968,7 +1979,7 @@ def __win_check_git_pull(path):
process.wait()
def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=False, no_deps=False):
def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=False, no_deps=False, selected_dependencies=None):
# import ipdb; ipdb.set_trace()
install_script_path = os.path.join(repo_path, "install.py")
requirements_path = os.path.join(repo_path, "requirements.txt")
@ -1980,6 +1991,13 @@ def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=Fa
if os.path.exists(requirements_path) and not no_deps:
print("Install: pip packages")
pip_fixer = manager_util.PIPFixer(manager_util.get_installed_packages(), comfy_path, manager_files_path)
# Create a set of selected dependency lines for quick lookup
selected_lines = set()
if selected_dependencies:
for dep in selected_dependencies:
selected_lines.add(dep.get('line', '').strip())
with open(requirements_path, "r") as requirements_file:
for line in requirements_file:
#handle comments
@ -1990,6 +2008,10 @@ def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=Fa
else:
line = line.split('#')[0].strip()
# Skip if selected_dependencies is provided and this line is not in the selected list
if selected_dependencies is not None and line.strip() not in selected_lines:
continue
package_name = remap_pip_package(line.strip())
if package_name and not package_name.startswith('#'):

View File

@ -494,7 +494,12 @@ async def task_worker():
global tasks_in_progress
async def do_install(item) -> str:
ui_id, node_spec_str, channel, mode, skip_post_install = item
if len(item) == 6:
ui_id, node_spec_str, channel, mode, skip_post_install, selected_dependencies = item
else:
# Backward compatibility
ui_id, node_spec_str, channel, mode, skip_post_install = item
selected_dependencies = []
try:
node_spec = core.unified_manager.resolve_node_spec(node_spec_str)
@ -503,7 +508,7 @@ async def task_worker():
return f"Cannot resolve install target: '{node_spec_str}'"
node_name, version_spec, is_specified = node_spec
res = await core.unified_manager.install_by_id(node_name, version_spec, channel, mode, return_postinstall=skip_post_install)
res = await core.unified_manager.install_by_id(node_name, version_spec, channel, mode, return_postinstall=skip_post_install, selected_dependencies=selected_dependencies)
# discard post install if skip_post_install mode
if res.action not in ['skip', 'enable', 'install-git', 'install-cnr', 'switch-cnr']:
@ -1388,7 +1393,9 @@ async def install_custom_node(request):
logging.error(SECURITY_MESSAGE_GENERAL)
return web.Response(status=404, text="A security error has occurred. Please check the terminal logs")
install_item = json_data.get('ui_id'), node_spec_str, json_data['channel'], json_data['mode'], skip_post_install
# Get selected dependencies if provided
selected_dependencies = json_data.get('selectedDependencies', [])
install_item = json_data.get('ui_id'), node_spec_str, json_data['channel'], json_data['mode'], skip_post_install, selected_dependencies
task_queue.put(("install", install_item))
return web.Response(status=200)
@ -1471,6 +1478,272 @@ async def install_custom_node_pip(request):
return web.Response(status=200)
@routes.post("/customnode/analyze_dependencies")
async def analyze_dependencies(request):
"""
Analyze dependencies for a custom node from git URL.
Fetches requirements.txt, checks installed packages, and returns dependency list with status.
"""
try:
json_data = await request.json()
url = json_data.get('url')
commit_id = json_data.get('commitId')
branch = json_data.get('branch')
if not url:
return web.json_response({'error': 'URL is required'}, status=400)
# Fetch requirements.txt from git repository
requirements_content = await fetch_requirements_from_git(url, commit_id, branch)
if requirements_content is None:
return web.json_response({
'success': True,
'requirements': None,
'dependencies': [],
'noRequirementsFile': True
})
# Parse requirements
dependencies = parse_requirements(requirements_content)
# Get installed packages
installed_packages = manager_util.get_installed_packages()
# Analyze each dependency with subdependencies
analyzed_dependencies = []
for dep_line in dependencies:
if not dep_line.strip() or dep_line.strip().startswith('#'):
continue
# Parse dependency line
parsed = manager_util.parse_requirement_line(dep_line)
if not parsed:
continue
package_name = parsed.get('package')
if not package_name:
# Fallback: extract from line if package is missing
import re
match = re.match(r'^([a-zA-Z0-9_.-]+)', dep_line.strip())
package_name = match.group(1) if match else "Unknown"
version_spec = parsed.get('version')
# Convert version_spec to string if it's a StrictVersion object
if version_spec is not None:
version_spec = str(version_spec)
normalized_name = package_name.lower().replace('-', '_')
# Check if already installed
installed_version = installed_packages.get(normalized_name)
status = 'new'
if installed_version:
status = 'installed'
# Convert version to string if it's not already (handle StrictVersion objects)
current_version_str = str(installed_version) if installed_version else None
# Get subdependencies using pip install --dry-run
# This is optional and failures should not block the main flow
subdependencies = []
# Skip subdependency analysis for already installed packages (not needed)
if status != 'installed':
try:
import subprocess
import sys
# Run pip install --dry-run to get subdependencies
# Some packages like pymeshlab can take longer due to complex dependency resolution
# Use a reasonable timeout - if it times out, we'll continue without subdependencies
result = subprocess.run(
[sys.executable, '-m', 'pip', 'install', '--dry-run', dep_line.strip()],
capture_output=True,
text=True,
timeout=45 # Increased timeout to 45 seconds
)
output = result.stdout + result.stderr
if output:
subdependencies = parse_dry_run_output(output, package_name, installed_packages)
except subprocess.TimeoutExpired:
# Timeout is not critical - continue without subdependencies
logging.debug(f"Subdependency analysis timed out for {package_name} (skipping subdependencies)")
subdependencies = []
except Exception as e:
# Any other error is not critical - continue without subdependencies
logging.debug(f"Failed to analyze subdependencies for {package_name}: {e}")
subdependencies = []
# Add main dependency (always add, even if subdependency analysis failed)
# Ensure all fields are properly set and clean
clean_package_name = str(package_name).strip() if package_name else "Unknown"
# Remove any None/null strings that might have been concatenated
clean_package_name = clean_package_name.replace('None', '').replace('null', '').strip()
if not clean_package_name:
clean_package_name = "Unknown"
analyzed_dependencies.append({
'name': clean_package_name,
'version': str(version_spec) if version_spec else None,
'line': dep_line.strip(),
'status': status,
'currentVersion': current_version_str,
'selected': status != 'installed', # Deselect if already installed
'subdependencies': subdependencies
})
return web.json_response({
'success': True,
'requirements': requirements_content,
'dependencies': analyzed_dependencies,
'noRequirementsFile': False
})
except Exception as e:
logging.error(f"Error analyzing dependencies: {e}")
traceback.print_exc()
return web.json_response({'error': str(e)}, status=500)
def parse_requirements(content):
"""Parse requirements.txt content into list of dependency lines."""
lines = []
for line in content.split('\n'):
line = line.strip()
if line and not line.startswith('#'):
lines.append(line)
return lines
def parse_dry_run_output(output, parent_name, installed_packages):
"""Parse pip install --dry-run output to extract subdependencies."""
import re
subdependencies = []
subdeps_map = {}
lines = output.split('\n')
for line in lines:
line = line.strip()
# Look for "Collecting package==version" lines
if 'Collecting ' in line and 'Using cached' not in line:
# Match: "Collecting package==version" or "Collecting package"
match = re.search(r'Collecting\s+([a-zA-Z0-9_.-]+(?:\[[^\]]+\])?)(?:\s*==\s*([^\s\(]+))?', line)
if match:
dep_name = match.group(1).split('[')[0].strip()
# Clean the name - remove any None/null strings
if dep_name:
dep_name = dep_name.replace('None', '').replace('null', '').strip()
dep_version = match.group(2).strip() if match.group(2) else None
# Clean version too
if dep_version:
dep_version = dep_version.replace('None', '').replace('null', '').strip() or None
# Skip the parent package itself
if dep_name.lower() == parent_name.lower():
continue
# Normalize name
normalized_name = dep_name.lower().replace('-', '_')
# Check if already in map (avoid duplicates)
if normalized_name not in subdeps_map:
# Check if already installed
installed_version = installed_packages.get(normalized_name)
status = 'installed' if installed_version else 'new'
current_version_str = str(installed_version) if installed_version else None
# Ensure name is always a string, not None
if not dep_name:
dep_name = "Unknown"
# Clean the name - remove any None/null strings
clean_dep_name = str(dep_name).strip().replace('None', '').replace('null', '').strip()
if not clean_dep_name:
clean_dep_name = "Unknown"
subdeps_map[normalized_name] = {
'name': clean_dep_name,
'version': str(dep_version) if dep_version else None,
'status': status,
'currentVersion': current_version_str,
'selected': status != 'installed'
}
# Also look for "Would install" lines which have more accurate version info
if 'Would install' in line:
# Match: "Would install package-version"
match = re.search(r'Would install\s+([a-zA-Z0-9_.-]+)-([\d.]+)', line)
if match:
dep_name = match.group(1)
dep_version = match.group(2)
normalized_name = dep_name.lower().replace('-', '_')
if normalized_name in subdeps_map:
# Update with more accurate version
subdeps_map[normalized_name]['version'] = dep_version
# Convert map to list
for normalized_name, dep_info in subdeps_map.items():
subdependencies.append(dep_info)
return subdependencies
async def fetch_requirements_from_git(url, commit_id=None, branch=None):
"""
Fetch requirements.txt from a git repository URL.
Supports GitHub URLs by converting to raw.githubusercontent.com.
"""
try:
# Extract GitHub repo info
if 'github.com' in url:
# Convert to raw GitHub URL
url = url.rstrip('/')
if url.endswith('.git'):
url = url[:-4]
# Extract owner/repo
match = re.search(r'github\.com[:/]([^/]+)/([^/]+)', url)
if not match:
return None
owner = match.group(1)
repo = match.group(2)
# Build raw URL
if commit_id:
raw_url = f"https://raw.githubusercontent.com/{owner}/{repo}/{commit_id}/requirements.txt"
elif branch:
raw_url = f"https://raw.githubusercontent.com/{owner}/{repo}/{branch}/requirements.txt"
else:
raw_url = f"https://raw.githubusercontent.com/{owner}/{repo}/main/requirements.txt"
# Try to fetch using aiohttp
async with aiohttp.ClientSession() as session:
async with session.get(raw_url) as response:
if response.status == 200:
return await response.text()
# Try with master branch if main fails
if 'main' in raw_url:
raw_url = raw_url.replace('/main/', '/master/')
async with session.get(raw_url) as response2:
if response2.status == 200:
return await response2.text()
else:
# For non-GitHub URLs, we'd need to clone temporarily
# For now, return None (can be enhanced later)
logging.warning(f"Non-GitHub URL not fully supported for dependency analysis: {url}")
return None
return None
except Exception as e:
logging.error(f"Error fetching requirements from git: {e}")
return None
@routes.post("/manager/queue/uninstall")
async def uninstall_custom_node(request):
if not is_allowed_security_level('middle'):

View File

@ -67,6 +67,7 @@ export class CustomNodesManager {
this.filter = '';
this.keywords = '';
this.restartMap = {};
this.analyzeDependenciesBeforeInstall = false; // Default: false
this.init();
@ -77,6 +78,36 @@ export class CustomNodesManager {
}
init() {
// Create checkbox for dependency analysis
const analyzeDepsCheckbox = $el("input", {
type: "checkbox",
id: "cn-analyze-deps-checkbox",
checked: this.analyzeDependenciesBeforeInstall,
onchange: (e) => {
this.analyzeDependenciesBeforeInstall = e.target.checked;
},
style: {
marginRight: "6px",
cursor: "pointer"
}
});
const analyzeDepsLabel = $el("label", {
for: "cn-analyze-deps-checkbox",
style: {
display: "flex",
alignItems: "center",
cursor: "pointer",
color: "#fff",
fontSize: "12px",
marginRight: "10px",
whiteSpace: "nowrap"
}
}, [
analyzeDepsCheckbox,
$el("span", { textContent: "Analyse dependencies before node installation" })
]);
const header = $el("div.cn-manager-header.px-2", {}, [
// $el("label", {}, [
// $el("span", { textContent: "Filter" }),
@ -84,6 +115,7 @@ export class CustomNodesManager {
// ]),
createSettingsCombo("Filter", $el("select.cn-manager-filter")),
$el("input.cn-manager-keywords.p-inputtext.p-component", { type: "search", placeholder: "Search" }),
analyzeDepsLabel,
$el("div.cn-manager-status"),
$el("div.cn-flex-auto"),
$el("div.cn-manager-channel")
@ -105,6 +137,421 @@ export class CustomNodesManager {
this.initGrid();
}
showDependencySelectorDialog(dependencies, onSelect) {
const dialog = new ComfyDialog();
dialog.element.style.zIndex = 1100;
dialog.element.style.width = "900px";
dialog.element.style.maxHeight = "80vh";
dialog.element.style.padding = "0";
dialog.element.style.backgroundColor = "#2a2a2a";
dialog.element.style.border = "1px solid #3a3a3a";
dialog.element.style.borderRadius = "8px";
dialog.element.style.boxSizing = "border-box";
dialog.element.style.overflow = "hidden";
const contentStyle = {
width: "100%",
display: "flex",
flexDirection: "column",
padding: "20px",
boxSizing: "border-box",
gap: "15px"
};
// Create scrollable table container with sticky header
const tableContainer = $el("div", {
style: {
maxHeight: "500px",
overflowY: "auto",
border: "1px solid #4a4a4a",
borderRadius: "4px",
backgroundColor: "#1a1a1a",
position: "relative"
}
});
// Create table
const table = $el("table", {
style: {
width: "100%",
borderCollapse: "separate",
borderSpacing: "0",
fontSize: "14px"
}
});
// Create table header with sticky positioning
const thead = $el("thead", {
style: {
position: "sticky",
top: "0",
zIndex: "10",
backgroundColor: "#2a2a2a",
boxShadow: "0 2px 4px rgba(0,0,0,0.3)"
}
}, [
$el("tr", {
style: {
backgroundColor: "#2a2a2a",
borderBottom: "2px solid #4a4a4a"
}
}, [
$el("th", {
textContent: "",
style: {
padding: "10px",
textAlign: "left",
width: "40px",
color: "#fff"
}
}),
$el("th", {
textContent: "Dependency Name",
style: {
padding: "10px",
textAlign: "left",
color: "#fff",
fontWeight: "bold"
}
}),
$el("th", {
textContent: "Current Version",
style: {
padding: "10px",
textAlign: "left",
color: "#fff",
fontWeight: "bold"
}
}),
$el("th", {
textContent: "Incoming Version",
style: {
padding: "10px",
textAlign: "left",
color: "#fff",
fontWeight: "bold"
}
})
])
]);
// Create table body
const tbody = $el("tbody", {});
// Create table rows for each dependency and its subdependencies
let rowIndex = 0;
dependencies.forEach((dep) => {
// Ensure name is not null/undefined and clean it
let depName = dep.name;
if (!depName || depName === 'null' || depName === 'None') {
// Fallback: extract from line
if (dep.line) {
depName = dep.line.split(/[=<>!~]/)[0].trim();
} else {
depName = "Unknown";
}
}
// Remove any "null" suffix that might have been appended
depName = String(depName).replace(/null$/i, '').trim();
const isInstalled = dep.status === 'installed';
const incomingVersion = dep.version || "NA";
const currentVersion = dep.currentVersion || "NA";
// Main dependency row
const row = $el("tr", {
style: {
backgroundColor: rowIndex % 2 === 0 ? "#1a1a1a" : "#222222",
borderBottom: "1px solid #3a3a3a"
}
}, [
$el("td", {
style: {
padding: "10px",
textAlign: "center"
}
}, [
$el("input", {
type: "checkbox",
checked: dep.selected,
onchange: (e) => {
dep.selected = e.target.checked;
},
style: {
cursor: "pointer",
width: "18px",
height: "18px"
}
})
]),
$el("td", {
style: {
padding: "10px",
color: isInstalled ? "#888" : "#fff"
}
}, [
$el("span", {
textContent: depName,
style: {
fontWeight: "500",
marginRight: isInstalled ? "8px" : "0"
}
}),
isInstalled ? $el("span", {
textContent: "Installed",
style: {
display: "inline-block",
backgroundColor: "#2a4a2a",
color: "#4a9",
padding: "2px 6px",
borderRadius: "3px",
fontSize: "10px",
fontWeight: "bold",
border: "1px solid #4a9"
}
}) : ''
]),
$el("td", {
textContent: currentVersion,
style: {
padding: "10px",
color: isInstalled ? "#4a9" : "#aaa",
fontFamily: "monospace"
}
}),
$el("td", {
textContent: incomingVersion,
style: {
padding: "10px",
color: "#fff",
fontFamily: "monospace"
}
})
]);
tbody.appendChild(row);
rowIndex++;
// Add subdependencies as indented rows
if(dep.subdependencies && dep.subdependencies.length > 0) {
dep.subdependencies.forEach((subdep) => {
// Ensure subdependency name is not null/undefined and clean it
let subdepName = subdep.name;
if (!subdepName || subdepName === 'null' || subdepName === 'None') {
subdepName = "Unknown";
}
// Remove any "null" suffix that might have been appended
subdepName = String(subdepName).replace(/null$/i, '').trim();
const subIsInstalled = subdep.status === 'installed';
const subIncomingVersion = subdep.version || "NA";
const subCurrentVersion = subdep.currentVersion || "NA";
const subRow = $el("tr", {
style: {
backgroundColor: rowIndex % 2 === 0 ? "#1a1a1a" : "#222222",
borderBottom: "1px solid #3a3a3a"
}
}, [
$el("td", {
style: {
padding: "10px",
textAlign: "center"
}
}, [
$el("input", {
type: "checkbox",
checked: subdep.selected,
onchange: (e) => {
subdep.selected = e.target.checked;
},
style: {
cursor: "pointer",
width: "18px",
height: "18px"
}
})
]),
$el("td", {
style: {
padding: "10px 10px 10px 30px",
color: subIsInstalled ? "#888" : "#aaa",
fontSize: "13px"
}
}, [
$el("span", {
textContent: "└─ " + subdepName,
style: {
fontWeight: "400",
marginRight: subIsInstalled ? "8px" : "0"
}
}),
subIsInstalled ? $el("span", {
textContent: "Installed",
style: {
display: "inline-block",
backgroundColor: "#2a4a2a",
color: "#4a9",
padding: "2px 6px",
borderRadius: "3px",
fontSize: "10px",
fontWeight: "bold",
border: "1px solid #4a9"
}
}) : ''
]),
$el("td", {
textContent: subCurrentVersion,
style: {
padding: "10px",
color: subIsInstalled ? "#4a9" : "#666",
fontFamily: "monospace",
fontSize: "13px"
}
}),
$el("td", {
textContent: subIncomingVersion,
style: {
padding: "10px",
color: "#aaa",
fontFamily: "monospace",
fontSize: "13px"
}
})
]);
tbody.appendChild(subRow);
rowIndex++;
});
}
});
table.appendChild(thead);
table.appendChild(tbody);
tableContainer.appendChild(table);
const content = $el("div", {
style: contentStyle
}, [
$el("h3", {
textContent: "Select Dependencies to Install",
style: {
color: "#ffffff",
backgroundColor: "#1a1a1a",
padding: "10px 15px",
margin: "0 0 10px 0",
width: "100%",
textAlign: "center",
borderRadius: "4px",
boxSizing: "border-box"
}
}),
$el("div", {
textContent: `${dependencies.filter(d => d.status === 'installed').length} already installed, ${dependencies.filter(d => d.status !== 'installed').length} to install`,
style: {
color: "#aaa",
fontSize: "12px",
marginBottom: "5px"
}
}),
tableContainer,
$el("div", {
style: {
display: "flex",
justifyContent: "space-between",
width: "100%",
gap: "10px",
marginTop: "10px"
}
}, [
$el("button", {
textContent: "Cancel",
onclick: () => {
onSelect(null); // Pass null to indicate cancellation
dialog.close();
},
style: {
flex: "1",
padding: "8px",
backgroundColor: "#4a4a4a",
color: "#ffffff",
border: "none",
borderRadius: "4px",
cursor: "pointer"
}
}),
$el("button", {
textContent: "Select All",
onclick: () => {
dependencies.forEach(dep => {
if (dep.status !== 'installed') {
dep.selected = true;
}
// Also select subdependencies
if(dep.subdependencies) {
dep.subdependencies.forEach(subdep => {
if(subdep.status !== 'installed') {
subdep.selected = true;
}
});
}
});
// Update checkboxes in the table
const checkboxes = tableContainer.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach((checkbox) => {
if(!checkbox.disabled) {
checkbox.checked = true;
}
});
},
style: {
padding: "8px 15px",
backgroundColor: "#4a6a4a",
color: "#ffffff",
border: "none",
borderRadius: "4px",
cursor: "pointer"
}
}),
$el("button", {
textContent: "Install Selected",
onclick: () => {
// Collect all selected dependencies (main + subdependencies)
const selected = [];
dependencies.forEach(d => {
if(d.selected) {
selected.push(d);
}
// Also include selected subdependencies
if(d.subdependencies) {
d.subdependencies.forEach(subdep => {
if(subdep.selected) {
selected.push(subdep);
}
});
}
});
onSelect(selected);
dialog.close();
},
style: {
flex: "1",
padding: "8px",
backgroundColor: "#4CAF50",
color: "#ffffff",
border: "none",
borderRadius: "4px",
cursor: "pointer"
}
}),
])
]);
console.log('[Dependency Dialog] Showing dialog with', dependencies.length, 'dependencies');
dialog.show(content);
console.log('[Dependency Dialog] Dialog shown');
}
showVersionSelectorDialog(versions, onSelect) {
const dialog = new ComfyDialog();
dialog.element.style.zIndex = 1100;
@ -1470,6 +1917,101 @@ export class CustomNodesManager {
}
}
// For install mode, analyze dependencies BEFORE starting installation
let selectedDependencies = [];
let dependencyDialogShown = false; // Track if dialog was shown
if(mode === "install" && this.analyzeDependenciesBeforeInstall) {
// Analyze dependencies for all items first (only if checkbox is enabled)
for (const hash of list) {
const item = this.grid.getRowItemBy("hash", hash);
if (!item) {
console.log('[Dependency Analysis] Item not found for hash:', hash);
continue;
}
const data = item.originalData;
console.log('[Dependency Analysis] Item data:', {
title: item.title,
files: data.files,
repository: data.repository,
hasFiles: !!data.files,
filesLength: data.files ? data.files.length : 0
});
// Try multiple ways to get the git URL
let gitUrl = null;
if(data.files && data.files.length > 0) {
gitUrl = data.files[0];
} else if(data.repository) {
gitUrl = data.repository;
}
if(gitUrl && (gitUrl.includes('github.com') || gitUrl.includes('.git'))) {
try {
this.showStatus(`Analyzing dependencies for ${item.title}...`);
console.log('[Dependency Analysis] Fetching dependencies for:', gitUrl);
const analyzeRes = await api.fetchApi('/customnode/analyze_dependencies', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
url: gitUrl,
commitId: data.commit_id,
branch: data.branch
})
});
console.log('[Dependency Analysis] Response status:', analyzeRes.status);
if(analyzeRes.status === 200) {
const analyzeData = await analyzeRes.json();
console.log('[Dependency Analysis] Response data:', {
success: analyzeData.success,
hasDependencies: !!analyzeData.dependencies,
dependenciesCount: analyzeData.dependencies ? analyzeData.dependencies.length : 0,
noRequirementsFile: analyzeData.noRequirementsFile
});
if(analyzeData.success && analyzeData.dependencies && analyzeData.dependencies.length > 0) {
console.log('[Dependency Analysis] Showing dialog with', analyzeData.dependencies.length, 'dependencies');
dependencyDialogShown = true;
// Show dependency selection dialog and wait for user
const userSelection = await new Promise((resolve) => {
this.showDependencySelectorDialog(analyzeData.dependencies, (selected) => {
console.log('[Dependency Analysis] User selected:', selected);
resolve(selected);
});
});
// If user cancelled (null), stop installation
if(userSelection === null) {
console.log('[Dependency Analysis] User cancelled installation');
this.showStatus("Installation cancelled");
return;
}
selectedDependencies = userSelection || [];
console.log('[Dependency Analysis] Selected dependencies:', selectedDependencies.length);
} else if(analyzeData.noRequirementsFile) {
console.log('[Dependency Analysis] No requirements.txt file found');
} else {
console.log('[Dependency Analysis] No dependencies to show');
}
} else {
const errorText = await analyzeRes.text();
console.error('[Dependency Analysis] API error:', analyzeRes.status, errorText);
}
} catch(e) {
console.error('[Dependency Analysis] Exception:', e);
// Continue with installation even if dependency analysis fails
}
} else {
console.log('[Dependency Analysis] Not a GitHub URL or no URL found:', gitUrl);
}
}
}
target.classList.add("cn-btn-loading");
this.showError("");
@ -1511,6 +2053,46 @@ export class CustomNodesManager {
data.mode = this.mode;
data.ui_id = hash;
// Add selected dependencies to data (including subdependencies)
// Only install selected dependencies - respect user's selection
const allSelected = [];
if(selectedDependencies.length > 0) {
selectedDependencies.forEach(d => {
// Add main dependency if selected
if(d.selected) {
allSelected.push({
name: d.name,
version: d.version,
line: d.line
});
}
// Add selected subdependencies
if(d.subdependencies) {
d.subdependencies.forEach(subdep => {
if(subdep.selected) {
allSelected.push({
name: subdep.name,
version: subdep.version,
line: `${subdep.name}${subdep.version ? '==' + subdep.version : ''}`
});
}
});
}
});
}
// Set selectedDependencies:
// - If dialog was shown: always set (even if empty) to respect user's selection
// - If dialog was not shown: don't set (install all dependencies - original behavior)
if(dependencyDialogShown) {
// User saw the dialog, respect their selection (even if empty)
data.selectedDependencies = allSelected;
} else if(allSelected.length > 0) {
// Dialog wasn't shown but we have selections (shouldn't happen, but just in case)
data.selectedDependencies = allSelected;
}
// If dialog wasn't shown and no selections, don't set selectedDependencies
// This means backend will install all dependencies (original behavior)
let install_mode = mode;
if(mode == 'switch') {
install_mode = 'install';

View File

@ -1,5 +1,155 @@
{
"custom_nodes": [
{
"author": "xmarre",
"title": "ComfyUI-DiffAid-Patches",
"reference": "https://github.com/xmarre/ComfyUI-DiffAid-Patches",
"files": [
"https://github.com/xmarre/ComfyUI-DiffAid-Patches"
],
"install_type": "git-clone",
"description": "A ComfyUI custom node pack implementing Diff-Aid-inspired inference-time text-conditioning patches for Flux and SDXL models."
},
{
"author": "wos-ai-studio",
"title": "ComfyUI-Title-Memo",
"reference": "https://github.com/xujianjian2004/ComfyUI-Title-Memo",
"files": [
"https://github.com/xujianjian2004/ComfyUI-Title-Memo"
],
"install_type": "git-clone",
"description": "A lightweight ComfyUI canvas annotation node with rich styling, built-in presets, and custom presets."
},
{
"author": "takkun",
"title": "ComfyUI-StepByStep-Sampler",
"reference": "https://github.com/TakkunRed/ComfyUI-StepByStep-Sampler",
"files": [
"https://github.com/TakkunRed/ComfyUI-StepByStep-Sampler"
],
"install_type": "git-clone",
"description": "ComfyUI StepByStep Sampler is a plugin for ComfyUI that provides a step-by-step sampling method for image generation. It allows users to generate images in a more controlled and iterative manner, making it easier to achieve desired results."
},
{
"author": "marduk191",
"title": "comfyui-nucleus",
"reference": "https://github.com/marduk191/comfyui-nucleus",
"files": [
"https://github.com/marduk191/comfyui-nucleus"
],
"install_type": "git-clone",
"description": "Nucleus Image (MoE diffusion) support for ComfyUI — backport of PR #13471"
},
{
"author": "ussaaron",
"title": "FrameFuse",
"reference": "https://github.com/headline-design/comfyui-framefuse",
"files": [
"https://github.com/headline-design/comfyui-framefuse"
],
"install_type": "git-clone",
"description": "ComfyUI nodes for stitching a still frame onto the start or end of an IMAGE video batch and trimming extra tail frames with optional audio sync alignment."
},
{
"author": "eniewold",
"title": "Subworkflow (reusable workflows)",
"reference": "https://github.com/eniewold/ComfyUI-Subworkflow",
"files": [
"https://github.com/eniewold/ComfyUI-Subworkflow"
],
"install_type": "git-clone",
"description": "Use ComfyUI workflows as reusable subworkflows via Subworkflow Input, Subworkflow Output, and Subworkflow nodes"
},
{
"author": "machinedelusions",
"title": "ComfyUI-FL-LTXTools",
"reference": "https://github.com/filliptm/ComfyUI-FL-LTXTools",
"files": [
"https://github.com/filliptm/ComfyUI-FL-LTXTools"
],
"install_type": "git-clone",
"description": "Experimental tools and motion controls for LTX-Video in ComfyUI"
},
{
"author": "serhiiyashyn-sf",
"title": "Face-Aligned Center",
"reference": "https://github.com/serhiiyashyn-sf/comfyui-face-aligned-center",
"files": [
"https://github.com/serhiiyashyn-sf/comfyui-face-aligned-center"
],
"install_type": "git-clone",
"description": "Batch-aware character centering for ComfyUI. Given a character sheet (multiple angles), scales every image so the face ends up at the same size and canvas position — including back-view angles, via a silhouette fallback tied to the batch's face scale. Includes a Fine-Tune node for per-image zoom/nudge with a live canvas preview, and an Anime Face Detect node for crop+mask using lbpcascade_animeface."
},
{
"author": "amortegui84",
"title": "Tile Upscale NB2",
"reference": "https://github.com/amortegui84/comfyui-tile-upscale-nb2",
"files": [
"https://github.com/amortegui84/comfyui-tile-upscale-nb2"
],
"install_type": "git-clone",
"description": "Tile-based upscaling nodes for ComfyUI — Nano Banana 2 compatible"
},
{
"author": "dorpxam",
"title": "LTX-2 Microscope",
"reference": "https://github.com/dorpxam/ComfyUI-LTX2-Microscope",
"files": [
"https://github.com/dorpxam/ComfyUI-LTX2-Microscope"
],
"install_type": "git-clone",
"description": "48-Layers Latent Previewer for Lightrick's LTX-2 model."
},
{
"author": "enviral-design",
"title": "Enviral Design Node Pack",
"reference": "https://github.com/EnviralDesign/comfyUI-enviral-design-node-pack",
"files": [
"https://github.com/EnviralDesign/comfyUI-enviral-design-node-pack"
],
"install_type": "git-clone",
"description": "Small, dependency-light ComfyUI utility nodes from Enviral Design."
},
{
"author": "newgrit1004",
"title": "Qwen3 Triton TTS",
"reference": "https://github.com/newgrit1004/ComfyUI-Qwen3-TTS-Triton",
"files": [
"https://github.com/newgrit1004/ComfyUI-Qwen3-TTS-Triton"
],
"install_type": "git-clone",
"description": "ComfyUI node wrapping qwen3-tts-triton for 7-mode Qwen3-TTS inference (Triton kernel fusion + TurboQuant KV cache)"
},
{
"author": "intelliprompt",
"title": "comfy-intelliprompt",
"reference": "https://github.com/galpt/comfy-intelliPrompt",
"files": [
"https://github.com/galpt/comfy-intelliPrompt"
],
"install_type": "git-clone",
"description": "intelliPrompt - An intelligent prompt optimizer for ComfyUI that fixes typos, balances parentheses, and enhances prompts"
},
{
"author": "mahilkr",
"title": "HunyuanWorld 3D World Generation",
"reference": "https://github.com/krmahil/comfyui-hunyuan-world",
"files": [
"https://github.com/krmahil/comfyui-hunyuan-world"
],
"install_type": "git-clone",
"description": "ComfyUI custom nodes for immersive 3D world generation using Tencent HunyuanWorld 1.0"
},
{
"author": "dailydoseofaiart",
"title": "ComfyUI-FPSFrameDrop",
"reference": "https://github.com/dailydoseofaiart/ComfyUI-FPSFrameDrop",
"files": [
"https://github.com/dailydoseofaiart/ComfyUI-FPSFrameDrop"
],
"install_type": "git-clone",
"description": "A node to drop frames from the output images to force the video to a lower FPS at the same playback speed."
},
{
"author": "comfyui-attic",
"title": "External LoRA Loader",

View File

@ -2209,13 +2209,16 @@
"AcademiaSD_Downloader",
"AcademiaSD_Gemini_Node",
"AcademiaSD_LTXVMultiFrames",
"AcademiaSD_LoopCounter",
"AcademiaSD_MultiLora",
"AcademiaSD_MultiPrompt",
"AcademiaSD_Numeric",
"AcademiaSD_Resolution",
"AcademiaSD_ResolutionDisplay",
"AcademiaSD_SaveAndSend",
"AcademiaSD_SaveCaption",
"AcademiaSD_TimeCalculator",
"AcademiaSD_VideoKeyframer",
"AcademiaVisionNode",
"IntegerBypasser",
"LoopCounterToFile",
@ -7132,6 +7135,9 @@
"BoyoPairedSaver",
"BoyoPromptInjector",
"BoyoPromptLoop",
"BoyoPromptRelayEncode",
"BoyoPromptRelayEncodeTimeline",
"BoyoPromptRelayLoraGate",
"BoyoQwenVLGrounding",
"BoyoResolutionCalc",
"BoyoSaver",
@ -7660,6 +7666,14 @@
"title_aux": "comfyui-sdnq"
}
],
"https://github.com/EnviralDesign/comfyUI-enviral-design-node-pack": [
[
"EnviralTextSplitByDelimiter"
],
{
"title_aux": "Enviral Design Node Pack"
}
],
"https://github.com/Eonizer/ComfyUI-bby-nodes": [
[
"TagFilterNode"
@ -9569,10 +9583,13 @@
"https://github.com/GoogleCloudPlatform/comfyui-google-genmedia-custom-nodes": [
[
"Gemini25FlashImage",
"Gemini31FlashImage",
"Gemini3ProImage",
"GeminiNode25",
"GeminiNode31",
"Imagen3TextToImageNode",
"Imagen4TextToImageNode",
"Imagen4UpscaleImageNode",
"Lyria2TextToMusicNode",
"Veo2GcsUriImageToVideoNode",
"Veo2ImageToVideoNode",
@ -10951,12 +10968,30 @@
],
"https://github.com/IAMCCS/IAMCCS-nodes": [
[
"IAMCCS-SuperNodes AU+IMG2VID Exec Finalize",
"IAMCCS-SuperNodes AU+IMG2VID Exec Planner",
"IAMCCS-SuperNodes AU+IMG2VID Exec Render",
"IAMCCS-SuperNodes AU+IMG2VID Exec VAE",
"IAMCCS-SuperNodes Second Stage",
"IAMCCS_AUIMG2VID_AudioTimeline",
"IAMCCS_AUIMG2VID_Continuity",
"IAMCCS_AUIMG2VID_DiskExtension",
"IAMCCS_AUIMG2VID_Finalize",
"IAMCCS_AUIMG2VID_KeyframeTimeline",
"IAMCCS_AUIMG2VID_Planner",
"IAMCCS_AUIMG2VID_ProjectTimelinePlanner",
"IAMCCS_AUIMG2VID_ReanchorLatent",
"IAMCCS_AUIMG2VID_RefreshPolicy",
"IAMCCS_AUIMG2VID_RuntimeBridge",
"IAMCCS_ApplyLoRAHooksToConditioning",
"IAMCCS_ApplyScheduledWanLoRAFromConditioning",
"IAMCCS_AudioExtender",
"IAMCCS_AudioExtensionMath",
"IAMCCS_AudioTimelineAssembler",
"IAMCCS_AudioTimelineGate",
"IAMCCS_AutoLinkArguments",
"IAMCCS_AutoLinkConverter",
"IAMCCS_BuildScheduledWanModelBank",
"IAMCCS_FluxKleinMultiGen",
"IAMCCS_GGUF_accelerator",
"IAMCCS_GetAutoLink",
@ -10966,7 +11001,19 @@
"IAMCCS_HwSupporterAny",
"IAMCCS_ImageResizeBatchSafe",
"IAMCCS_IntValueMonitor",
"IAMCCS_LTX2_AudioPromptDirector",
"IAMCCS_LTX2_BlendLatentBridge",
"IAMCCS_LTX2_CinematicLineStacker",
"IAMCCS_LTX2_CinematicMultiGenPlanner",
"IAMCCS_LTX2_CinematicPromptComposer",
"IAMCCS_LTX2_CinematicPromptRelayAdapter",
"IAMCCS_LTX2_CinematicRefLatentControl",
"IAMCCS_LTX2_CinematicShotAudioSelector",
"IAMCCS_LTX2_CinematicShotLineBuilder",
"IAMCCS_LTX2_CinematicShotPlanner",
"IAMCCS_LTX2_CinematicV2VAssetSelector",
"IAMCCS_LTX2_CinematicV2VTimelineLineBuilder",
"IAMCCS_LTX2_CinematicV2VTimelinePlanner",
"IAMCCS_LTX2_ConditionNextLatentWithPrevOverlap",
"IAMCCS_LTX2_ContextLatent",
"IAMCCS_LTX2_ControlPreprocess",
@ -11005,11 +11052,23 @@
"IAMCCS_LTX2_TimeFrameCount",
"IAMCCS_LTX2_Validator",
"IAMCCS_LatentTailSlice",
"IAMCCS_LazyAnySwitch",
"IAMCCS_LoadImagesFromDirLite",
"IAMCCS_LoadResizeSegmentFromDir",
"IAMCCS_Ltx2HelperModules_AudioTimeline",
"IAMCCS_Ltx2HelperModules_Continuity",
"IAMCCS_Ltx2HelperModules_DiskExtension",
"IAMCCS_Ltx2HelperModules_Finalize",
"IAMCCS_Ltx2HelperModules_KeyframeTimeline",
"IAMCCS_Ltx2HelperModules_Planner",
"IAMCCS_Ltx2HelperModules_ProjectTimelinePlanner",
"IAMCCS_Ltx2HelperModules_ReanchorLatent",
"IAMCCS_Ltx2HelperModules_RefreshPolicy",
"IAMCCS_Ltx2HelperModules_RuntimeBridge",
"IAMCCS_ModelWithLoRA",
"IAMCCS_ModelWithLoRA_LTX2",
"IAMCCS_ModelWithLoRA_LTX2_Staged",
"IAMCCS_ModelWithLoRA_RuntimeBridge",
"IAMCCS_MotionBridgeLoad",
"IAMCCS_MotionBridgeSave",
"IAMCCS_MotionScale",
@ -11018,17 +11077,25 @@
"IAMCCS_MoveAheadEnforcer",
"IAMCCS_MultiSwitch",
"IAMCCS_MultilinePromptSplitter8",
"IAMCCS_ProjectTimelinePlanner",
"IAMCCS_QWEN_VL_FLF",
"IAMCCS_QWEN_VL_FLF_Advanced",
"IAMCCS_QwenMultiGen",
"IAMCCS_SamplerAdvancedVersion1",
"IAMCCS_SegmentPlanFromPlanner",
"IAMCCS_SegmentPlanner",
"IAMCCS_SegmentPlannerLinked",
"IAMCCS_SegmentPlannerSettings",
"IAMCCS_SegmentSwitch",
"IAMCCS_SelectScheduledWanModelFromConditioning",
"IAMCCS_SelectScheduledWanModelPairFromConditioning",
"IAMCCS_SetAutoLink",
"IAMCCS_SourceFramesToDisk",
"IAMCCS_SourceRangeFromSegmentPlan",
"IAMCCS_StartDirToVideoLatent",
"IAMCCS_StartImagesToVideoLatent",
"IAMCCS_SupernodeBase",
"IAMCCS_SupernodeModule",
"IAMCCS_ThreeSegmentPlanner",
"IAMCCS_TwoSegmentPlanner",
"IAMCCS_VAEDecodeTiledSafe",
@ -11048,6 +11115,8 @@
"IAMCCS_WanImageMotionPro_Simple",
"IAMCCS_WanImageMotion_AdaIN",
"IAMCCS_WanIndexedPromptEncode",
"IAMCCS_WanLoRAHookSchedule",
"IAMCCS_WanLoRARuntimeBridge",
"IAMCCS_WanLoRASchedule",
"IAMCCS_WanLoRAStack",
"IAMCCS_WanLoRAStackModelIO",
@ -13894,7 +13963,10 @@
],
"https://github.com/Limbicnation/ComfyUI-PromptGenerator": [
[
"Limbicnation_NegativePrompt",
"Limbicnation_PromptCombiner",
"Limbicnation_PromptGenerator",
"Limbicnation_PromptRefiner",
"Limbicnation_StyleApplier"
],
{
@ -15804,11 +15876,13 @@
"NLConstantColor",
"NLContextDebug",
"NLEdit",
"NLFitFrame",
"NLFromModelSpace",
"NLImageInfoDebug",
"NLLTXVImgToVideoInplaceAtIndex",
"NLLinearToLog",
"NLLogToLinear",
"NLMatch",
"NLMerge",
"NLOCIOConvert",
"NLPreview",
@ -16779,9 +16853,13 @@
"CRTPostProcess",
"CRT_AddSettingsAndPrompt",
"CRT_AudioTranscript",
"CRT_AudioTranscriptPipeOut",
"CRT_DynamicPromptScheduler",
"CRT_FileBatchPromptScheduler",
"CRT_ImageLoaderCrawlBatch",
"CRT_IsolateInput",
"CRT_IsolateInputCLIPSeg",
"CRT_IsolateOutput",
"CRT_KSamplerBatch",
"CRT_KSamplerBatchAdvanced",
"CRT_LTX23AutoDownload",
@ -17418,20 +17496,39 @@
"GeomPackAddNormalsToPointCloud",
"GeomPackAlphaWrap",
"GeomPackBackdraftView",
"GeomPackBooleanBlender",
"GeomPackBooleanCGAL",
"GeomPackBoolean",
"GeomPackBoolean_BlenderExact",
"GeomPackBoolean_LibiglCGAL",
"GeomPackCheckNormals",
"GeomPackCombineMeshes",
"GeomPackCombineMeshesBatch",
"GeomPackComputeNormals",
"GeomPackConnectedComponents",
"GeomPackCreatePrimitive",
"GeomPackDecimateMesh",
"GeomPackDecimate_CGALEdgeCollapse",
"GeomPackDecimate_DecimatePro",
"GeomPackDecimate_FastSimplification",
"GeomPackDecimate_QuadricEdgeCollapse",
"GeomPackDecimate_VertexClustering",
"GeomPackDegenerateFaces",
"GeomPackDepthNormalsToMesh",
"GeomPackDetectSelfIntersections",
"GeomPackExtractLargestComponent",
"GeomPackExtractSkeleton",
"GeomPackFillHoles",
"GeomPackFillHoles_CGAL",
"GeomPackFillHoles_GPU",
"GeomPackFillHoles_IglFan",
"GeomPackFillHoles_PyMeshFix",
"GeomPackFillHoles_PyMeshLab",
"GeomPackFillHoles_Trimesh",
"GeomPackFixNormals",
"GeomPackFixNormals_IglBfs",
"GeomPackFixNormals_IglRaycast",
"GeomPackFixNormals_IglSignedDist",
"GeomPackFixNormals_IglWinding",
"GeomPackFixNormals_Trimesh",
"GeomPackFixSelfIntersectionsByPerturbation",
"GeomPackFixSelfIntersectionsByRemoval",
"GeomPackGetMeshFilename",
@ -17461,20 +17558,63 @@
"GeomPackPreviewMeshVTK",
"GeomPackPreviewMeshVTKBatch",
"GeomPackReconstructSurface",
"GeomPackReconstruct_AlphaShape",
"GeomPackReconstruct_BallPivoting",
"GeomPackReconstruct_ConvexHull",
"GeomPackReconstruct_Poisson",
"GeomPackRemesh",
"GeomPackRemeshBlender",
"GeomPackRemeshCGAL",
"GeomPackRemeshGPU",
"GeomPackRemeshSelfIntersections",
"GeomPackRemeshWithTexture",
"GeomPackRemesh_BlenderBlocks",
"GeomPackRemesh_BlenderSharp",
"GeomPackRemesh_BlenderVoxel",
"GeomPackRemesh_CGAL",
"GeomPackRemesh_GPU",
"GeomPackRemesh_GeogramAniso",
"GeomPackRemesh_GeogramSmooth",
"GeomPackRemesh_InstantMeshes",
"GeomPackRemesh_MMG",
"GeomPackRemesh_PMPAdaptive",
"GeomPackRemesh_PMPUniform",
"GeomPackRemesh_PyMeshLab",
"GeomPackRemesh_QuadWild",
"GeomPackRemesh_QuadriFlow",
"GeomPackRemoveDegenerateFaces",
"GeomPackSaveMesh",
"GeomPackSaveMeshBatch",
"GeomPackSharpenMesh",
"GeomPackSharpen_FastEffective",
"GeomPackSharpen_GuidedNormal",
"GeomPackSharpen_L0Minimize",
"GeomPackSharpen_LibiglUnsharp",
"GeomPackSharpen_NonIterative",
"GeomPackSharpen_TwoStep",
"GeomPackSharpen_UnsharpMask",
"GeomPackSkeleton_EdgeCollapse",
"GeomPackSkeleton_Teasar",
"GeomPackSkeleton_VertexClusters",
"GeomPackSkeleton_Wavefront",
"GeomPackSmoothMesh",
"GeomPackSmooth_HCLaplacian",
"GeomPackSmooth_Laplacian",
"GeomPackSmooth_Taubin",
"GeomPackSmooth_TrimeshLaplacian",
"GeomPackSmooth_TrimeshTaubin",
"GeomPackSplitByField",
"GeomPackSubsamplePointCloud",
"GeomPackTextureToGeometry",
"GeomPackTransformMesh",
"GeomPackUVUnwrap",
"GeomPackUV_BlenderCube",
"GeomPackUV_BlenderCylinder",
"GeomPackUV_BlenderSmart",
"GeomPackUV_BlenderSphere",
"GeomPackUV_CuMesh",
"GeomPackUV_LibiglARAP",
"GeomPackUV_LibiglHarmonic",
"GeomPackUV_LibiglLSCM",
"GeomPackUV_Xatlas",
"GeomPackVisualizeNormalField",
"RefineMesh",
"ScrambleIntField"
@ -18008,6 +18148,7 @@
"RSCropImage",
"RSInsertCropImage",
"RSOutpaint",
"RSPrompts",
"RSSaveImage",
"RS_Last_Frame",
"RS_Saturation",
@ -22207,6 +22348,17 @@
"title_aux": "Fens-Simple-Nodes"
}
],
"https://github.com/TakkunRed/ComfyUI-StepByStep-Sampler": [
[
"StepByStepGridSampler",
"StepByStepSampler",
"StepStepComparer",
"StepStepPlayer"
],
{
"title_aux": "ComfyUI-StepByStep-Sampler"
}
],
"https://github.com/TakkunRed/comfyui_checkpoint_preset_manager": [
[
"CheckpointPresetNode"
@ -24046,7 +24198,14 @@
"FD_SeedreamImage",
"FD_Upload",
"FD_ZImageTurboGenImage",
"FD_imgToText_Doubao"
"FD_imgToText_Doubao",
"GPTImageEdit",
"MaoziEcommercePromptGenerator",
"MaoziPromptListSelector",
"NodeToggleByID",
"ZhiYiImageTextNode",
"ZhiYiImageToImageNode",
"ZhiYiTextGenNode"
],
{
"title_aux": "Comfyui_Fd_Nodes"
@ -26355,9 +26514,10 @@
],
"https://github.com/akawana/ComfyUI-Folded-Prompts": [
[
"ExecutionBlockerBreaker",
"FPFoldedPrompts",
"FPTab",
"FPTabbedTextArea",
"FPTabedTextPassthrough",
"FPTextAreaPlus",
"FPTextCleanAndSplitt"
],
@ -27170,12 +27330,33 @@
"InpaintCropNB2",
"InpaintStitchNB2",
"NB2AddAlpha",
"NanoBanana2MaskGen"
"NB2Florence2RegionSelector",
"NB2OpenAIImageEdit",
"NB2SmartRegionMask",
"NanoBanana2MaskGen",
"SmartMaskCrop",
"SmartMaskStitch"
],
{
"title_aux": "ComfyUI-Inpaint-CropStitch-NB2"
}
],
"https://github.com/amortegui84/comfyui-tile-upscale-nb2": [
[
"FlorenceMaskAlign",
"MaskBBoxCrop",
"TileCollect",
"TileCrop",
"TileCropNB2",
"TileExtract",
"TileInfo",
"TileStitch",
"TileStitchNB2"
],
{
"title_aux": "Tile Upscale NB2"
}
],
"https://github.com/amtarr/ComfyUI-TextureAlchemy": [
[
"AOApproximator",
@ -29314,6 +29495,7 @@
"https://github.com/bollerdominik/ComfyUI-load-lora-from-url": [
[
"AssertNotBlack",
"BytePlusVideoGeneration",
"CutImageByMask",
"GeminiImage2GenAI",
"ImageResize+",
@ -30084,7 +30266,6 @@
"Flux2KleinKSamplerExperimental",
"Flux2KleinMaskRefController",
"Flux2KleinRefLatentController",
"Flux2KleinRefLatentWeight",
"Flux2KleinSectionedEncoder",
"Flux2KleinTextEnhancer",
"Flux2KleinTextRefBalance",
@ -30151,6 +30332,7 @@
"AD_frame_replace",
"AD_keyframe_trend_preview",
"AD_latent_history",
"AD_media_trim_visual",
"AD_pingpong_vedio",
"AD_sch_IPA",
"AD_sch_image_merge",
@ -30159,8 +30341,11 @@
"AD_sch_prompt_stack",
"AD_sch_value",
"AD_video_merge",
"AI_DoubaoWebPreview",
"AI_GLM_image",
"AI_GLM_text",
"AI_Gemini3_ImageEdit",
"AI_Gemini3_Img2T",
"AI_ModelScopeImageEdit",
"AI_ModelScopeT2I",
"AI_ModelScope_image",
@ -30183,6 +30368,7 @@
"Coordinate_Index2Text",
"Coordinate_MarkRender",
"Coordinate_SplitIndex",
"Coordinate_create_mask",
"Coordinate_fromImage",
"Coordinate_fromMask",
"Coordinate_loadImage",
@ -30198,10 +30384,12 @@
"Easy_QwenEdit2509",
"IO_EasyMark",
"IO_ImageSaveOverwrite",
"IO_LoadAudioBatch",
"IO_LoadImgBatch",
"IO_LoadImgList",
"IO_LoadShotBatch",
"IO_LoadTextBatch",
"IO_LoadVideoBatch",
"IO_PathProcessor",
"IO_RegexPreset",
"IO_ShotCreate",
@ -30302,6 +30490,7 @@
"Stack_pre_Mark2",
"Stack_sample_data",
"Stack_text",
"UniversalAPI",
"basicIn_Boolean",
"basicIn_Remap_slide",
"basicIn_Sampler",
@ -30480,10 +30669,10 @@
"text_StrMatrix",
"text_converter",
"text_filter",
"text_interPrompt",
"text_list_combine",
"text_loadText",
"text_modifier",
"text_mulAngle",
"text_mul_Join",
"text_mul_Split",
"text_saveText",
@ -32817,6 +33006,10 @@
"GrokVideoNode",
"GrokVideoReferenceNode",
"GrowMask",
"HappyHorseImageToVideoApi",
"HappyHorseReferenceVideoApi",
"HappyHorseTextToVideoApi",
"HappyHorseVideoEditApi",
"HitPawGeneralImageEnhance",
"HitPawVideoEnhance",
"Hunyuan3Dv2Conditioning",
@ -34263,6 +34456,14 @@
"title_aux": "SDXL Auto Prompter"
}
],
"https://github.com/dailydoseofaiart/ComfyUI-FPSFrameDrop": [
[
"VHSForceFPSKeepSpeed"
],
{
"title_aux": "ComfyUI-FPSFrameDrop"
}
],
"https://github.com/danTheMonk/comfyui-int-and-float": [
[
"FloatToInt",
@ -35230,6 +35431,14 @@
"title_aux": "ComfyUI-LTXVideo-Extra"
}
],
"https://github.com/dorpxam/ComfyUI-LTX2-Microscope": [
[
"LTX2Microscope"
],
{
"title_aux": "LTX-2 Microscope"
}
],
"https://github.com/dothings/comfyui_placeholder_prompting": [
[
"PlaceholderPrompting"
@ -36046,6 +36255,17 @@
"title_aux": "ComfyUI-Image-Cipher"
}
],
"https://github.com/eniewold/ComfyUI-Subworkflow": [
[
"BaseSubworkflow",
"SWF_SubworkflowInput",
"SWF_SubworkflowModifier",
"SWF_SubworkflowOutput"
],
{
"title_aux": "Subworkflow (reusable workflows)"
}
],
"https://github.com/envy-ai/ComfyUI-ConDelta": [
[
"ApplyConDelta",
@ -36894,6 +37114,14 @@
"title_aux": "ComfyUI-FL-DiffVSR"
}
],
"https://github.com/filliptm/ComfyUI-FL-LTXTools": [
[
"FL_LTX_MotionBoost"
],
{
"title_aux": "ComfyUI-FL-LTXTools"
}
],
"https://github.com/filliptm/ComfyUI_FL-ClearVoice": [
[
"FL_ClearVoice_ModelLoader",
@ -37003,6 +37231,7 @@
"FL_ColorPicker",
"FL_CreateShapeImageOnPath",
"FL_Dalle3",
"FL_DepthBlur",
"FL_DirectoryCrawl",
"FL_Dither",
"FL_FILM",
@ -37849,6 +38078,15 @@
"title_aux": "ComfyUI-String-Similarity"
}
],
"https://github.com/galpt/comfy-intelliPrompt": [
[
"IntelliPromptResolutionPresetLatent",
"intelliPrompt"
],
{
"title_aux": "comfy-intelliprompt"
}
],
"https://github.com/game4d/ComfyUI-BDsInfiniteYou": [
[
"InfiniteYou_Image",
@ -39189,6 +39427,15 @@
"title_aux": "ComfyUI-ReplenishNodes"
}
],
"https://github.com/headline-design/comfyui-framefuse": [
[
"FrameFuse",
"FrameFuseTrimEnd"
],
{
"title_aux": "FrameFuse"
}
],
"https://github.com/heheok/comfyui_wan2.1_vace_infinite_helpers": [
[
"CyclicCharacterAndBackgroundPrompt",
@ -40413,7 +40660,7 @@
"https://github.com/ialhabbal/OcclusionMask": [
[
"BatchLoadImages",
"ImageOcclusion"
"OcclusionMask"
],
{
"title_aux": "OcclusionMask"
@ -40692,6 +40939,7 @@
[
"Light-Tool: AddBackground",
"Light-Tool: AddBackgroundV2",
"Light-Tool: AspectRatioPadder",
"Light-Tool: BoundingBoxCropping",
"Light-Tool: Calculate",
"Light-Tool: ConvertNumType",
@ -44836,6 +45084,18 @@
"title_aux": "Hollow Preserve"
}
],
"https://github.com/krmahil/comfyui-hunyuan-world": [
[
"HYWorldFullPipeline",
"HYWorldImage2Pano",
"HYWorldSceneGen",
"HYWorldText2Pano",
"HYWorldUnloadModels"
],
{
"title_aux": "HunyuanWorld 3D World Generation"
}
],
"https://github.com/kukuo6666/ComfyUI-Equirect": [
[
"CubemapToEquirect",
@ -44997,7 +45257,8 @@
"Leon_StableDiffusion_35_API_Node",
"Leon_StableDiffusion_3_Ultra_API_Node",
"Leon_StableDiffusion_XL_API_Node",
"Leon_String_Combine_Node"
"Leon_String_Combine_Node",
"Leon_Yellow_Tint_Cleaner_Node"
],
{
"nodename_pattern": "^\ud83e\udd16 Leon",
@ -48146,6 +48407,14 @@
"title_aux": "marduk191 workflow settings"
}
],
"https://github.com/marduk191/comfyui-nucleus": [
[
"NucleusCLIPLoader"
],
{
"title_aux": "comfyui-nucleus"
}
],
"https://github.com/marduk191/comfyui_qwen_runninghub": [
[
"RunningHubImageEnhancer",
@ -48471,6 +48740,7 @@
"mrmth_ModelMathNode",
"mrmth_NoiseMathNode",
"mrmth_ScriptInput",
"mrmth_StackUnBatcher",
"mrmth_VAEMathNode",
"mrmth_VideoMathNode",
"mrmth_ag_AudioMathNode",
@ -48894,6 +49164,8 @@
"ExecutionGateControl",
"FrameAccumulator",
"FrameContextFit",
"FreeVRAMIfLoaded",
"FreeVRAMUnlessLoaded",
"ImageExists",
"ImageFallback",
"ImageModeRouter",
@ -50221,6 +50493,15 @@
"title_aux": "ComfyUI-StyleShot"
}
],
"https://github.com/newgrit1004/ComfyUI-Qwen3-TTS-Triton": [
[
"Qwen3TTSCustomVoice",
"Qwen3TTSVoiceClone"
],
{
"title_aux": "Qwen3 Triton TTS"
}
],
"https://github.com/ngosset/ComfyUI-ImageSimilarity": [
[
"Image Similarity"
@ -55462,6 +55743,16 @@
"title_aux": "ComfyUI_Nimbus-Pack"
}
],
"https://github.com/serhiiyashyn-sf/comfyui-face-aligned-center": [
[
"AnimeFaceDetect",
"FaceAlignedCenter",
"FaceAlignedFineTune"
],
{
"title_aux": "Face-Aligned Center"
}
],
"https://github.com/serious-factory/ComfyUI-MultiTalkPromptSchedule": [
[
"MultiTalkPromptSchedule"
@ -59816,6 +60107,7 @@
],
"https://github.com/ussoewwin/ComfyUI-NunchakuFluxLoraStacker": [
[
"ColorFilter",
"FastGroupsBypasserV2",
"FluxLoraMultiLoader",
"LoadImageUssoewwin",
@ -60364,6 +60656,7 @@
"VRGDG_CreateFinalVideo",
"VRGDG_CreateFinalVideo_SRT",
"VRGDG_CreateSilentAudio",
"VRGDG_CyclingTextPicker",
"VRGDG_DisplayIndex",
"VRGDG_DurationIndexFloat",
"VRGDG_Extract_Frame_Number",
@ -60411,6 +60704,8 @@
"VRGDG_LoadTextAdvanced",
"VRGDG_LoadVideos",
"VRGDG_LocalLLM",
"VRGDG_LyricSegmentDurationMerger",
"VRGDG_LyricSegmentJsonFixer",
"VRGDG_LyricsEmotionMerger",
"VRGDG_MakeLUT",
"VRGDG_ManualLyricsExtractor",
@ -60428,6 +60723,8 @@
"VRGDG_PadVideoWithLastFrame",
"VRGDG_PostRunIndexStepper",
"VRGDG_PromptCreatorUI",
"VRGDG_PromptCreatorUI_V2",
"VRGDG_PromptMapJsonFixer",
"VRGDG_PromptSpitterWithIndex",
"VRGDG_PromptSplitter",
"VRGDG_PromptSplitter2",
@ -60459,6 +60756,7 @@
"VRGDG_SpeedCharacterLoraTraining",
"VRGDG_SplitPrompt_T2I_I2V",
"VRGDG_StoryBoardCreator",
"VRGDG_StoryGroupJsonFixer",
"VRGDG_String2Json",
"VRGDG_StringConcat",
"VRGDG_SuperGemmaGGUFChat",
@ -61805,6 +62103,15 @@
"title_aux": "ComfyUI-AutoGuidance"
}
],
"https://github.com/xmarre/ComfyUI-DiffAid-Patches": [
[
"Flux2DiffAidSparsePatch",
"SDXLDiffAidCrossAttentionPatch"
],
{
"title_aux": "ComfyUI-DiffAid-Patches"
}
],
"https://github.com/xmarre/ComfyUI-Flux2Klein-Conditioning-Toolkit": [
[
"Flux2KleinConditioningEnhancer",
@ -62017,6 +62324,14 @@
"title_aux": "ComfyUI_Camera"
}
],
"https://github.com/xujianjian2004/ComfyUI-Title-Memo": [
[
"Title_Memo"
],
{
"title_aux": "ComfyUI-Title-Memo"
}
],
"https://github.com/xuxiao305/ComfyUI-ImageBatchUtils": [
[
"ImageBatchCount",
@ -62436,6 +62751,7 @@
"ycCanvasBBox",
"ycCanvasBBoxMask",
"ycImageCrop",
"ycImageCropBatchApply",
"ycImageCropInteractive",
"ycimagebrushmask"
],