Add list_preset_display_names to flake_io.py and return display_names
from the /flakes/presets API endpoint. Use the display name (falling
back to last path segment) in the preset picker grid thumbnails.
Add display_names to /flakes/list API response and use them in the
Load Existing Flake picker to show the flake's display name instead
of the path filename as the grid item label.
Closes#137
- Make controlnet type a dropdown listing available types (openpose, depth, canny, etc.)
- Replace input image text field with file selector (left side) with image preview
- Redesign CN card layout: image preview on left, type/model/sliders on right
- Add labeled sliders (Str, Start, End) for controlnet
- Auto-set cover image from first controlnet input image if no cover exists
- Add /flakes/cn_types endpoint for listing controlnet types
- Add 'inputs' browse type for file picker to select input images
- Add fetchCnTypes API function
The _shorten_filenames function was adding both the full filename and the
stem (without extension) to dropdown lists, causing models like VAEs and
text encoders to appear twice (e.g. 'ae' and 'ae.safetensors'). Now only
the stem is returned.
Backend resolution helpers (_resolve_model_name) are added to translate
stem-only names back to full filenames when loading checkpoin/vae/
text_encoder/controlnet models, ensuring backwards compatibility with
existing YAML files that store full filenames.
Mirror the model-preset base-path support on the flake side:
Backend:
- save_flake() now accepts base_root_index, output_path, and old_name,
using the same semantics as save_preset(). Renames/moves migrate the
YAML and its cover image.
- /flakes/save now passes those through to save_flake.
Frontend:
- Base Path dropdown + Output Path text field on the flake create AND
edit overlays (populated from /flakes/roots?type=flakes).
- Path prefill from display name + flake type only fires in create
mode; edit mode seeds from the existing flake name and treats it
as user-edited.
- Save call now uses /flakes/save with base_root_index/output_path/
old_name, and flake-stack.js updates the entry's name if the saved
canonical name differs (i.e. the flake was moved).
Backend:
- /flakes/roots?type=model_presets exposes registered roots so the UI
can label Default vs Extra base paths.
- save_preset() now accepts base_root_index (which root to write to)
and output_path (relative location under that root), and old_name
(so renames/moves migrate the YAML and its cover image cleanly).
- Returns the canonical saved name so the UI can register the new
preset under the actual on-disk path.
- ModelPreset gained a display_name field stored alongside the YAML.
Frontend:
- New Base Path dropdown and Output Path text field on the create/edit
preset overlay. Output path auto-prefills from family_folder/preset_name
(snake-cased) until the user types in it.
- Preset name input is now a display name; the file path is independent.
- Edit mode passes old_name so the backend moves the YAML when the
user changes either the base path or the output path.
- YAML: write 'variants:' going forward; reads still accept 'options:'
as a legacy alias and migrate it on next save.
- Flake.variants dataclass field renamed; entry payload now reads
'variant' for the per-stack override (legacy 'option' still works).
- UI: button labels (+ variant group), field selector label (Variants),
empty-state text, alert wording all updated.
- /flakes/meta returns both 'variants' and 'options' keys for one
transitional release.
- README updated to reflect the new key.
save_flake() prepends img/<family>/ to the requested name when family
is set, but the API returned the original user-typed path, so the
freshly created grid item pointed at a non-existent name and any
subsequent run errored with FileNotFoundError. Return the resolved
name from the backend and use it for the grid entry.
- Drop top-level path/strength keys on save when loras[] is present
- Strip them on read so the UI never sees the legacy duplicate
- Resolve LoRA-derived covers to the sibling image path on save so YAML
never stores a .safetensors path under cover_image
- Backend cover lookup keeps fall-through support for legacy YAMLs that
still point at a .safetensors weight
When the user selects a LoRA on a flake and no cover has been picked
yet, fetch the LoRA's sibling image (same basename, .png/.jpg/.webp/...)
from models/loras/ and use it as the flake's default cover.
Triggers from all three LoRA selection paths (file browser, dropdown
change, dropdown blur) but only for the first LoRA on the flake, and
only when no cover file has been chosen by the user. Adds a server
endpoint /flakes/lora_sibling_image mirroring the existing checkpoint
sibling endpoint, with a shared helper.
- Add /flakes/checkpoint_sibling_image endpoint to find an image next to
the selected checkpoint with the same basename.
- In the preset editor, auto-load that image as cover when a checkpoint is
selected, but only if no cover already exists.
- Poll preset widget value in FlakeModelPreset so cover updates immediately
when the user swaps presets via the dropdown.
Closes#52
- Replace module-level _BROWSE_ROOTS with dynamic _get_browse_roots() called
at request time. This fixes the Empty folder bug caused by evaluating paths
before ComfyUI has finished registering them.
- Search ALL configured roots for a given type and merge/deduplicate results,
matching the behavior of folder_paths.get_filename_list().
- Add security check per-root so symlink escapes are skipped rather than fatal.
Closes#44