- Split run_name on "/" and "\" and reject empty, "." and ".." parts, so
a Windows-style "..\foo" can no longer resolve outside model_compare
and let the index-0 archive step rename an unrelated output folder
- Reject drive-letter names and require the resolved directory to sit
strictly below output/model_compare after symlinks are followed
- Nested run names such as project/date/sweep still work
- Checkpoint Folder Iterator loads one checkpoint per queued run from a
folder (relative to models/checkpoints or absolute), so a whole folder
can be swept with only one model in memory at a time
- Model Compare Sheet saves each run's image as a tile under
output/model_compare/<run_name>/ and rebuilds a labeled contact sheet
from disk every run, so the grid survives between independent prompts
- Starting a sweep at index 0 archives stale tiles to a timestamped folder
- Running past the last checkpoint raises a clear error instead of
wrapping, so an over-queued batch never restarts and archives a
finished sweep
- Checkpoints load from the scanned absolute path, so folders outside the
configured roots work as the tooltip promises
- Extract the LoRA Folder Batch folder-scanning, natural-sort and regex
filter helpers into kikotools/base/model_folders.py so both tools share
one implementation
- google-generativeai is deprecated and emits a FutureWarning at node
load; google-genai is Google's supported replacement
- Image analysis now uses genai.Client().models.generate_content
instead of the module-level configure/GenerativeModel API
- Model listing reads supported_actions, the new SDK's name for
supported_generation_methods
- Install instructions, requirements.txt, and README updated to the
new package name
Drop RETURN_NAMES so ComfyUI shows the output as STRING, matching the original Project File Path Generator. Links connect by slot index, so existing workflows are unaffected.
Builds a save prefix like MyProject/2026-10-13/images/image for a save
node's filename_prefix, replacing djz-nodes' Project File Path Generator
with a fresh implementation:
- Same inputs, root defaults to empty (prefixes are already relative to
the output folder, so "output" nested as output/output/...)
- Optional date folder; IS_CHANGED tracks the date instead of forcing a
re-run on every queue
- Components are split on / and \ with '..' segments dropped, so a path
can't climb out of the output folder
- Only real file extensions are stripped (render_v1.5 keeps its dot)
- The separator option is applied last instead of being undone by
normpath; an empty filename raises a clear error
- Close PIL images and NamedTemporaryFile handles before deleting the
files; Windows refuses to delete open files (WinError 32)
- Set USERPROFILE alongside HOME: expanduser ignores HOME on Windows
- Compare realpaths in the nested save-prefix test; Windows temp dirs
use 8.3 short names (RUNNER~1)
save_paths is reachable without auth, so saving "/" made every media
file on the machine servable. Reject filesystem/drive roots, the home
directory and its ancestors (realpath-resolved, so symlinks count), and
ignore such entries already in config.json.
ComfyUI registers custom_nodes in folder_names_and_paths, so treating
every registered folder as a download root let a queued prompt drop a
.py file there that runs on the next restart.
- Skip custom_nodes when collecting allowed roots
- save_response only writes model/data extensions (.safetensors, .gguf,
.ckpt, .pth, .json, ...), so any future code-holding folder is still
protected
- KikoSaveImage: reject absolute or '..' filename_prefix directories that
resolved outside the output folder
- Film grain: use a local torch.Generator instead of reseeding the global
RNG; strength 0 no longer skips the toe adjustment
- Purge VRAM: IS_CHANGED returns NaN so caching never skips the purge
- Resolution calculator: clamp outputs to >= 8
- Plot sampler params: font size floor of 1 for images under 32px wide
- Gemini prompt: drop Image.fromarray mode= argument (removed in Pillow)
- Reject filenames with path components; reduce server-derived names
(Content-Disposition, CivitAI redirect, URL) to a safe basename
- save_path must resolve inside models_dir or a registered model folder
(including extra_model_paths.yaml roots); relative paths resolve
against ComfyUI's base path
- Only http/https for user URLs and redirects; drop the Authorization
header on cross-host redirects
- Stream to <file>.part and rename on success, removing the partial file
on any failure, so a dropped connection no longer leaves a truncated
model that later runs treat as complete
- 60s timeout on every request; shared streaming loop in BaseDownloader
- Custom downloader honours Content-Disposition before the default name
/view served any readable file (e.g. ~/.ssh/id_rsa) to anyone who could
reach the server; the only guard was a '..' substring check.
- Resolve paths with realpath and require commonpath containment in the
saved paths or ComfyUI input/output directories
- /view serves image/video/audio only, /thumbnail and load_media images
only; the extension check applies to the resolved path, so symlinks
can't smuggle other files
- /images 403s outside the roots; page/per_page validated and clamped
- /list_directories (folder picker) returns directory names only
- load_media refuses disallowed paths from a tampered selections.json
- Route handlers moved to module level so they are unit tested
- Update stale tests to the (image, info) return contract
- LoRA strength strings: step <= 0 looped forever and reversed ranges
returned [] (ZeroDivisionError later); now raise ValueError, and cap
generated values at 1000
- Flux sampler params: unparseable steps/guidance/shift/denoise/seed
tokens raise with the field name instead of being dropped, and an
empty LoRA folder raises instead of returning (None, [])
- Detect Flux schnell via unet_config guidance_embed (the ModelType.FLOW
check never matched Flux)
- IS_CHANGED: re-run Flux params when a seed is '?'; LoRA folder batch
hashes file list + mtimes instead of always re-executing
- LoRA folder scan uses commonpath containment across all lora roots
- Prompt separators must be whole lines; failed encodes raise
Previously split_latent_batch and join_latent_batch only handled the
"samples" key, silently dropping metadata like noise_mask or batch_index.
This broke inpaint and masked workflows after a round-trip conversion.
Add 4 utility nodes for converting between batched tensors and lists,
eliminating the dependency on Impact Pack for this common operation:
- ImageBatchToImageList (OUTPUT_IS_LIST)
- ImageListToImageBatch (INPUT_IS_LIST)
- LatentBatchToLatentList (OUTPUT_IS_LIST)
- LatentListToLatentBatch (INPUT_IS_LIST)
JS Math.random() only has 53 bits of integer precision, making the
64-bit range produce non-uniform values. 32-bit (0xFFFFFFFF) is the
standard ComfyUI seed range and works correctly in both Python and JS.
Also removes the redundant mode input from SeedHistoryNode, relying on
ComfyUI's built-in control_after_generate widget instead.
Refs #43
ComfyUI is converting nodes_latent.py to V3 Schema on October 8th, which will
break direct imports of LatentBatch. This commit replaces the import with a
local implementation copied directly from ComfyUI source code.
Changes:
- Removed: from comfy_extras.nodes_latent import LatentBatch
- Added: Local batch_latents() and reshape_latent_to() functions
- Updated: latentbatch.batch() calls to use batch_latents()
- Added: torch and comfy.utils imports for tensor operations
- Added: Comprehensive unit tests for latent batching functionality
The local implementation is functionally identical to the original and ensures
the node will continue working after the V3 schema migration.
Test Coverage:
- 5 new tests in TestLatentBatchingFunctions class
- All 16 tests passing (11 existing + 5 new)
- Tests cover tensor operations, batch indexing, and reshape logic
- Add auto-batching functionality to split large LoRA collections into manageable chunks
- Implement batch_size parameter to control number of LoRAs per batch (default: 25)
- Add batch_index parameter to select which batch to process
- Include batch tracking metadata in LORA_PARAMS for visualization
- Display batch info in plot parameters when available
- Update lora_list output to show batch header when auto-batching is enabled
- Add comprehensive tests for batching functionality
- Update documentation with detailed auto-batching usage instructions
This feature prevents UI disconnection issues when processing large numbers of LoRAs
by allowing users to process them in smaller batches sequentially.
- Implement film grain effect with customizable parameters (scale, strength, saturation, toe, seed)
- Use pure PyTorch operations for better GPU utilization (no OpenCV dependencies)
- Apply ITU-R BT.709 color space conversion for accurate grain distribution
- Implement screen blend mode for better highlight preservation
- Add channel-specific weighting matching real film characteristics (3x blue, 2x red)
- Preserve alpha channel when present
- Add comprehensive test suite (20 tests covering all functionality)
- Include documentation and example workflow
- Register node under ComfyAssets/image category
Improvements over reference implementation:
- More efficient memory management avoiding numpy/OpenCV conversions
- Better grain mixing algorithm with proper color science
- Improved performance through PyTorch-native operations
BREAKING CHANGE: Node categories now use emoji-based organization
Add 6 new xyz-helper nodes adapted from comfyui-essentials-nodes:
- FluxSamplerParams: FLUX-optimized parameter generator with batch support
- LoRAFolderBatch: Batch process multiple LoRAs from folders
- PlotParameters: Visualize parameter effects with graphs
- SamplerSelectHelper: Intelligent sampler selection with recommendations
- SchedulerSelectHelper: Optimal scheduler selection for samplers
- TextEncodeSamplerParams: Combined text encoding and parameter management
Changes:
- Port and enhance nodes from comfyui-essentials (now in maintenance mode)
- Add comprehensive documentation with attribution to original author (cubiq)
- Create example workflows for xyz-helpers tools
- Update all node categories to use emoji-based organization
- Fix all unit tests to pass with new category system
- Update README with xyz-helpers section and attribution
Attribution: xyz-helpers adapted from github.com/cubiq/ComfyUI_essentials
All tests passing (318 pass, 2 skip)
- Add new image_scale_down_by tool for downscaling images/latents
- Add display_any.js web component for node display
- Include comprehensive unit tests for the new tool
- Add AnyType class that inherits from str and overrides __ne__ to always return False
- This matches ComfyUI's type checking system for wildcard inputs
- Based on implementation from ComfyUI_essentials
- Add comprehensive tests for AnyType behavior
- Fixes type mismatch errors when connecting any node type
- Change from ('*', {}) to ('*') for proper ComfyUI wildcard type
- Update test to match the corrected syntax
- Fixes 'Return type mismatch' error when connecting nodes
- Universal input acceptance for any data type
- Two display modes: raw value and tensor shape
- Extracts tensor shapes from nested structures
- Comprehensive unit tests with 100% coverage
- Full documentation with usage examples
- OUTPUT_NODE for UI display functionality
- Update pyproject.toml to use black's default line-length of 88
- This matches what the CI workflow expects (black --check without args)
- Reformat all Python files to comply with the new line length
- This will prevent CI failures due to formatting discrepancies
- Add GeminiPromptNode for AI-powered prompt engineering
- Integrates with Google's Gemini API for prompt generation
- Includes various prompt templates and generation modes
- Add comprehensive tests and documentation
- Register node in ComfyAssets category
- Add code quality tools: flake8, mypy, black, pre-commit
- Add .gitattributes for line ending consistency
- Add .secrets.baseline for secret scanning
- Update GitHub workflows for better CI/CD
- Update documentation formatting and examples
- Add CLAUDE.md for AI assistant guidance
- Add scripts directory for automation tools
- Update project configuration in pyproject.toml
- Improve type hints and code formatting across all modules
- Update test configurations and fixtures
- Add ImageToMultipleOfNode for image dimension adjustment
- Ensures image dimensions are multiples of specified values
- Supports both padding and cropping modes
- Useful for model-specific dimension requirements
- Add tests and documentation
- Register node in ComfyAssets category