New nodes:
- Isulion Censored Part: blur/pixelate/black bar/noise over a mask and/or
a percent rectangle; accepts 2D/3D/4D masks and fails closed (blacks the
item out) instead of passing an uncensored image through
- Prompt Vault Save/Load: named prompt library stored in ComfyUI's user
directory (outside the checkout, so updates never conflict), seeded from
prompt_vault.example.json; Load re-runs when the vault changes
Refactor:
- SimpleSelectorNode base: ~20 selector nodes use an instance RNG instead
of reseeding the global random module (same seed => same output)
- Theme handlers declare DISPLAY_NAME; theme package auto-discovers modules
- __init__ imports node classes directly
Fixes:
- net_utils: re-validate every redirect hop, unwrap IPv4-mapped IPv6,
block NAT64 and all non-global addresses (SSRF)
- Multiple Prompt Generator: no duplicate prompts for themes listed in two
categories; 6 themes missing from every category are now reachable
- Shutdown node: parameter renamed to match its "any" input (TypeError)
- ConfigManager: deterministic (sorted) merge order, warns on key
collisions; drop stale space_colony copy from tropical_paradise_config
- Mega Prompt V3: seed honored again with randomize=disable
Breaking: Civitai api_key widget removed (use CIVITAI_API_TOKEN), absolute
paths refused by Load Images, Negative Prompt pools de-duplicated (shorter
"strict" output), Dynamic Random theme order is now alphabetical.
Tooling: pytest suite (51 tests), GitHub CI (compileall, pytest, ruff),
ruff config, uv.lock.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- IsuCollageNode: faithful port of ImageProcessor.calculateLayout
(float rects, per-row scaling factor) validated bit-exact against the
TypeScript original over 63 cases; optional 'width' widget (default 1024)
- load_images_node: stop padding images to a uniform size (that destroyed
aspect ratios and leaked black bands into tiles); output is now an
OUTPUT_IS_LIST of native-size tensors, matching the React app behavior
- IsuCollageNode: INPUT_IS_LIST to receive the full list in one call;
unwrap scalar widgets that ComfyUI also wraps in lists (seed/width)
- Rasterization snaps float rects via cumulative rounding so the <=1px
error spreads across all tiles instead of the last one; rows always
fill the canvas width exactly