- 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
- Add .comfyignore so `comfy node publish` ships only the runtime
package: __init__.py, kikotools/, web/, examples/, README, LICENSE,
pyproject.toml, requirements.txt
- Exclude tests/, scripts/, .github/, dev tooling configs, contributor
docs, and the stray example.py reference file (not imported anywhere)
- Registry scanner flagged 1.1.1 on five info-level pattern matches;
two were in tests/ and the historical Model.eval matches came from
example.py, none of which should be in the published archive
- Bump version to 1.1.2
- 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
Combines #56-#63:
- torch >=2.11.0, pillow >=12.2.0, mypy >=1.20.0, pytest-mock >=3.15.1,
pre-commit >=4.5.1 in both pyproject.toml and requirements-dev.txt
(Dependabot only edited pyproject, but CI installs requirements-dev.txt)
- actions/checkout v7, actions/cache v6, softprops/action-gh-release v3
across all workflows, including the new test/coverage/js jobs
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.
The image loader's config.json/selections.json (one user's saved folders
and selections) and the Gemini model cache were committed, so every
install shipped them as defaults, and running from a symlinked checkout
dirtied the tree. Untrack them and ignore them, plus gemini_config.json
which would hold an API key. All loaders already handle the files being
absent.
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
A Windows console on a legacy code page (cp1252, or cp437 in cmd)
raises UnicodeEncodeError on emoji. The startup banner printed a 🫶
prefix and display names like "Model Downloader 🌐", which aborts
loading the whole node pack. Same approach as ComfyUI_PromptManager:
- Banner prints ASCII-only display names (emoji stay in the UI names)
- Preset validation messages print "1024x1024" instead of "1024×1024"
- Explicit UTF-8 for text files (Windows defaults to cp1252)
- Regression test imports the package with a strict cp1252/cp437 stdout
- 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)
tests.yml only ran inline smoke scripts on Ubuntu, never the pytest
suite, so broken tests went unnoticed on main. Mirror ComfyUI_PromptManager:
- pytest on ubuntu/windows/macos x Python 3.10-3.13 (fail-fast off)
- separate coverage job enforcing fail_under = 85
- syntax check every web/*.js as an ES module
- CPU-only torch on Linux to avoid the ~2.5 GB CUDA wheel
- Groups have no node-menu hook, so the menu-hook refactor dropped their
custom color entry; add it via getCanvasMenuItems using the group under
the mouse, as the frontend's own Comfy.GroupOptions does
- The "Auto-shade Title" setting was read but never applied
- Share one hidden color input instead of three
- Don't mark the canvas dirty while merely building the node menu
Replace monkey-patches of LGraphCanvas.onMenuNodeColors and the
canvas/node menu getters (applied after a 500ms timeout, and scraping
.litecontextmenu DOM for "No color") with the frontend's
getNodeMenuItems/getCanvasMenuItems extension hooks. Custom colors move
into a "Custom Colors" submenu; follow-execution state moves to module
scope so repeated setup() calls no longer stack wrappers.
The backend now 403s folders outside the saved paths. Show the full path
and add it only on an explicit click; server-side refusals (e.g. a
too-broad folder) are shown in the status line.
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)