68 Commits
Author SHA1 Message Date
Mehdi Chaid 0caf422e1d feat: queue captions animate start images before the video jobs (#484) 2026-11-09 21:35:18 -05:00
Mehdi Chaid da1b782282 feat: image metadata merges stacks into one compact node (#436) 2026-10-21 17:46:05 -04:00
Mehdi Chaid 2e6aef56a0 feat: Flake Generate Animation node with video overlay (#434) 2026-10-21 13:39:07 -04:00
Mehdi Chaid b9fe43f4fc feat: Flake Animate Stack and Combo nodes (#432)
Compose animate flakes onto flake_anim_data: LoRAs model-only (high/low on Wan 2.2), joined prompts, stems and an optional start image. The Flake Stack/Combo widgets, load picker and queue combos take an anim kind.
2026-10-21 13:35:49 -04:00
Mehdi Chaid 5a5870990b feat: Flake Animate Preset and Preset Combo nodes (#430) 2026-10-21 13:30:22 -04:00
Mehdi Chaid bf2efecac7 feat: serve family registry to the frontend, add diffusion model and CLIP type fields (#360)
Server: GET /flakes/families serves the flake_families registry, plus
/flakes/diffusion_models and /flakes/clip_types for the preset editor.

Web: utils.js fetches the registry and exposes familySpec/familyFromFolder.
The hardcoded literals stay as a bootstrap fallback and are only replaced
once a real payload arrives, so a failed fetch degrades to the previous
behaviour rather than breaking the editor. flake-modal and preset-modal
now derive families from the shared helpers instead of keeping three more
private copies of the list.

Preset editor gains a diffusion-model picker and a text-encoder type
dropdown, hides Clip Skip for families whose encoder is not CLIP, and
seeds a new preset from its family defaults. The registry is warmed at
extension setup because the sliders are write-once and modals build
synchronously.

Verified against a running server: all three endpoints respond and
Krea2/Turbo appears in the FlakeModelPreset model_family dropdown.
2026-09-07 17:20:11 -04:00
Mehdi Chaid 13da022e49 fix: revert widget detach in #216 — keep model_family in node.widgets (#223)
Closes #223. The previous #216 fix (commit 2db236a) detached the
familyWidget from node.widgets to hide it. That introduced three
regressions:

1. Generation failed with "Required input is missing: model_family".
   The widget was the only carrier for the required model_family value
   in the serialized prompt; once detached, prompt validation rejected
   every job.

2. Node sizes were reset on reload. _updateFamilyVisibility called
   node.setSize(node.computeSize()) on every state transition, and on
   workflow load the 200ms poll fired a transition after onConfigure
   restored the saved size — overriding it.

3. Flake Stack items vanished on reload. Detaching the widget shifted
   the widget value order in the saved JSON: only [flakes_json_value]
   was serialized, but the reload code (correctly) still has the
   widget present, so the saved JSON string landed in model_family
   and flakes_json kept its empty default.

Fix:
- Keep familyWidget permanently in node.widgets so serialization is
  stable and the required input is always sent.
- Hide it visually by stacking computeSize=[0,-4], type="hidden",
  hidden=true, AND a no-op draw override (covers ComfyUI frontends
  that don't honor type/hidden for canvas-drawn COMBO widgets).
- Drop node.setSize from the visibility transition (rely on
  setDirtyCanvas to repaint).
- Defer the initial sync to setTimeout(0) so onConfigure has hydrated
  link state before we read it.
- Add _recoverShiftedWidgets in flake_stack.js onConfigure for
  FlakeStack and FlakeCombo: if model_family looks like JSON and
  flakes_json is at its empty default, swap them so workflows saved
  by the broken version recover their stack contents on next open.
2026-05-20 23:38:41 -04:00
Mehdi Chaid 0bc7720214 fix: rewrite FlakeDataSplitSelect and IntoFlakeDataSelect nodes (closes #164, closes #165)
FlakeDataSplitSelect (#164):
- Remove 'selected_pins' STRING from Python INPUT_TYPES (was causing node load failure)
- Store pin selection purely in node.properties._split_pins
- Rewrite JS widget with attached-button dropdown style

IntoFlakeDataSelect (#165):
- Remove all optional fields from Python INPUT_TYPES; use None-sentinel pattern
  so only connected inputs override the original flake_data
- JS now uses node.addInput/removeInput for dynamic pins — no default pins,
  no hidden widget fields interfering with click events
- Dropdown styled as select + attached button (matching Load Image node)
- Chips show active pins with x to remove
2026-05-14 15:58:31 -04:00
Mehdi Chaid ad2929a80c fix: redesign FlakeDataSplitSelect and IntoFlakeDataSelect pin management
FlakeDataSplitSelect could not be added to workflow because removeInitialPins
called node.removeOutput/addOutput which could fail during node creation.
Switch to applyPinVisibility (hide/show existing pin slots) instead of
dynamically removing/adding pins, which is safer and avoids the crash.

IntoFlakeDataSelect: hide widget-type fields (filename_prefex, width, height,
steps, cfg, sampler_name, scheduler) by default; show them as label + widget
rows only when added via dropdown. Redesign [+] button with neutral Load Image
style styling and add hover effect. Remove dedicated [-] button since chips
have individual delete (x) buttons. For widget-type pins, display inline
label + input widget instead of a square input pin.

Fixes #152, Fixes #153
2026-05-14 14:17:52 -04:00
Mehdi Chaid 6e2fe634db feat: add Flake Generate node - KSampler + VAE Decode + Save Image wrapper (#141)
Creates FlakeGenerate node that takes flake_data input, runs KSampler, VAE Decode, and SaveImage internally. Displays seed widget with randomize/increment/decrement controls, 2x2 preview grid (reusing flake-preview.js), and generated image preview in a single DOM widget.
2026-05-14 10:12:27 -04:00
Mehdi Chaid cba2916cfa fix(ui): dynamic pin add/remove for Flake Data Split/Into Select nodes
- Replace hide/show visibility approach with dynamic addOutput/removeOutput
  and addInput/removeInput for proper pin management
- On node creation, remove all default pins and add only selected ones
- On workflow load (onConfigure), clear all dynamic pins and rebuild from
  saved properties
- Remove OUTPUT_NODE from FlakeDataSplitSelect (not an output node)
- Add pin selector UI with +/- buttons that dynamically adds/removes pins
- Export DEFAULT_SPLIT_PINS and DEFAULT_INTO_PINS for use in onConfigure

Closes #139
2026-05-13 21:16:22 -04:00
Mehdi Chaid 122c50d174 fix: implement Preview Flake Data with 2x2 grid and click-to-view overlays 2026-05-13 21:13:51 -04:00
Mehdi Chaid 2390c94654 feat: add Preview Flake Data node with 4-item info grid
- Python backend: new PreviewFlakeData class that takes FLAKE_DATA input
  and passes it through unchanged, marked as OUTPUT_NODE for execution
- JavaScript frontend: custom widget showing a 2x2 grid with Models,
  Prompts, Parameters, and Metadata categories
- Clicking a category card opens an overlay with consolidated information
- Handles combo node scenarios by displaying all available data fields
- Registers the new node in __init__.py NODE_CLASS_MAPPINGS

Closes #122
2026-05-13 12:42:54 -04:00
Mehdi Chaid 3d15d895f2 feat: redesign Flake Data Split/Into Select nodes with dynamic pin selector
Replace yes/no group toggles on FlakeDataSplitSelect with a dropdown + +/- button
UI for individually adding/removing output pins. Similarly, redesign
IntoFlakeDataSelect to use dynamic input pins instead of FLAKES_MODEL/COND/SAMPLER
bundle types, allowing override of individual fields from an incoming FLAKE_DATA.

- Python: Add selected_pins/active_pins hidden STRING widgets for state tracking
- Python: IntoFlakeDataSelect now takes individual optional inputs (MODEL, CLIP,
  VAE, etc.) and overrides only activated pins from the incoming FLAKE_DATA
- JS: Add flake-data-select.js with pin selector dropdown + button widgets
- JS: Register handlers for FlakeDataSplitSelect and IntoFlakeDataSelect nodes
- JS: Show/hide outputs and inputs based on selected pin state

Closes #119
2026-05-13 12:32:11 -04:00
Mehdi Chaid 1938ae4433 fix(ui): preserve saved dimensions and set min width for new nodes 2026-05-07 00:13:05 -04:00
Mehdi Chaid fd7f2dae23 fix(ui): revert flake_stack.js to working version 2026-05-07 00:06:17 -04:00
Mehdi Chaid c317e4fdf5 fix(ui): default sizes, + cursor, preserve dimensions, bigger preset buttons 2026-05-06 23:11:09 -04:00
Mehdi Chaid b45af993d6 fix(ui): revert flake_stack.js extension to restore custom widgets 2026-05-06 18:56:30 -04:00
Mehdi Chaid 2ff14658bb fix(ui): use native family widget, remove gaps, preserve dimensions 2026-05-06 16:57:49 -04:00
Mehdi Chaid e2c4e64cc7 fix(nodes): robustly remove hidden widget input pins via splice and onConfigure 2026-05-06 16:22:04 -04:00
Mehdi Chaid d7858fbcdd fix(nodes): remove hidden widget input pins from flake nodes 2026-05-06 15:49:30 -04:00
Mehdi Chaid 6ab581f040 refactor: split flake_stack.js into focused modules
Decomposes the ~3800-line flake_stack.js monolith into maintainable
modules:

- api.js        – all server API calls
- utils.js      – DOM helpers, sliders, inputs, drag indicators
- modal.js      – overlay modal infrastructure
- flake-modal.js – flake create/edit modal
- preset-modal.js – preset create/edit modal + preset option refresh
- pickers.js    – file browser, flake picker, preset picker
- widgets/      – per-node widget setups
  - flake-stack.js
  - flake-combo.js
  - flake-model-preset.js
  - flake-model-combo.js
- queue.js      – frontend combination queueing logic
- flake_stack.js – entry point, imports everything and registers extension

Fixes #59
2026-05-01 15:06:12 -04:00
Mehdi Chaid d6f77c73a6 feat: redesign preset selection UI with visual picker popup
- Add openPresetPicker() that shows presets in a searchable grid with
  cover images, matching ComfyUI Load Image dropdown styling.
- Rewrite FlakeModelPreset widget: remove dropdown, add 'Select Preset'
  and 'Create Preset' buttons. When selected, show cover image with
  preset name and hover buttons for Remove/Modify.
- Update FlakeModelCombo widget: remove dropdown, use the visual picker
  when clicking 'Add Preset'.

Fixes #54, Fixes #55, Fixes #57
2026-05-01 14:16:10 -04:00
Mehdi Chaid 8e411b4133 fix: refresh preset options immediately after creating a preset
Adds cache-busting to the preset list fetch and makes widget DOM
updates more robust by trying multiple element selectors. Also
forces a canvas redraw so existing nodes reflect the new preset
without requiring a ComfyUI reload.

Fixes #56
2026-05-01 14:11:05 -04:00
Mehdi Chaid 0b48242fbd fix: make file browser search null-safe and remove redundant keyup listener
Adds String() coercion and null-safety to the file browser search
filter to prevent 'No matches' when entries have unexpected types.
Removes redundant keyup listener since input already covers text changes.

Fixes #58
2026-05-01 14:09:04 -04:00
Mehdi Chaid f7edf61d79 fix(grid-item): show all LoRAs in dropdown when YAML has multiple
Sync entry.loras to the length of the YAML's loras array so every LoRA
gets a strength slider in the grid item panel.

Closes #48
2026-04-29 14:55:35 -04:00
Mehdi Chaid 7573d71c68 feat(checkpoint-image): auto-set preset cover from sibling image and update on swap
- 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
2026-04-29 14:54:03 -04:00
Mehdi Chaid ffcfcb10b9 fix(configs): refresh preset dropdown immediately after create/update
Update the DOM <select> options in addition to the widget's internal
values array, and include FlakeModelCombo nodes in the refresh.

Closes #51
2026-04-29 14:50:39 -04:00
Mehdi Chaid 83ffcf87e6 fix(file-picker): double-click to select file and improve search
- Add dblclick handler on file rows to immediately select and close.
- Add keyup fallback for search filtering.
- Add Enter key support to select the first matching file.
- Focus search input when dialog opens.

Closes #50
2026-04-29 14:49:14 -04:00
Mehdi Chaid 40c50f373b fix(new-flake): remove default empty options group
Stop passing data: { options: {} } when opening the create modal so the
options field is not pre-added to activeFields by default.

Closes #49
2026-04-29 14:47:34 -04:00
Mehdi Chaid 54a74e51b4 fix(slider): allow arbitrary decimal values instead of snapping to step
Remove Math.round(v / step) * step from clamp so typed values like 4.7
are preserved. Drag and button clicks still use step math naturally.

Closes #53
2026-04-29 14:46:51 -04:00
Mehdi Chaid 007820c54f Fix option dropdown centering and option font size in item panel
- Increase select and option font-size from 10px to 13px
- Increase height from 22px to 26px to fit larger text
- Fix asymmetric padding (0 18px 0 4px → 0 18px) so selected text is
  truly centered across the full width, not offset by the chevron
- Add text-align:center to each <option> so open dropdown items are centered

Closes #47
2026-04-28 16:42:10 -04:00
Mehdi Chaid 1aa9cb878a Load Existing picker: show all flakes and add double-click selection
- Stop filtering out already-added flakes from the picker list
- Add double-click handler on flake thumbnails to select+close immediately
- Add double-click on folder items to navigate into them
- Update both FlakesStack and FlakesCombo handleLoad call sites

Closes #46
2026-04-28 16:40:09 -04:00
Mehdi Chaid 2f4915bc37 Improve URL toggle and link icon styling in preset and LoRA editors
- Model Preset: move URL input above checkpoint path selector
- Model Preset: make toggle button bigger (14px) with flex centering
- Model Preset: make link icon blue (#4a9eff)
- Flake LoRA editor: same bigger toggle button and blue link icon

Closes #45
2026-04-28 16:38:17 -04:00
Mehdi Chaid 4aa1f7e357 Redesign Load Existing picker with folder navigation and model_presets exclusion
- openFileLoadPicker now accepts {flakes, directories} and builds a folder tree
- Folders rendered as large 📁 icons with labels; clicking navigates into them
- Breadcrumb path bar shows current location; click to return to root
- Up-folder item (..) shown when inside a subfolder
- Search bar filters all flakes globally regardless of folder
- Exclude model_presets/ from both directory tree and search results
- Update both FlakesStack and FlakesCombo handleLoad call sites

Closes #43
2026-04-28 15:09:10 -04:00
Mehdi Chaid ca6f62fbfc Fix checkpoint and LoRA file pickers: correct root path and search bar
- Replace defaultPath: 'img' with '' for both checkpoints and loras pickers
  so they open at the model root instead of a non-existent img/ subfolder
- Add real-time search bar to openFileBrowser overlay filtering files/folders
  in the current directory by name
- Show 'No matches' when search yields no results

Closes #42
2026-04-28 15:04:21 -04:00
Mehdi Chaid b83f24a17d Preserve optional field order in flake YAML on save/load
- Save: build ordered dict by iterating activeFields so YAML keys follow
  the user-dragged order
- Load: derive activeFields from Object.keys(data) order (Python preserves
  insertion order via yaml.safe_dump sort_keys=False)
- Fallback appends any fields not present in the key order

Closes #41
2026-04-28 15:01:27 -04:00
Mehdi Chaid b7b529ba1f Style option dropdowns in item panel to match LoRA slider palette
- Add makePanelDropdown helper with dark background (#1a1a1a), #333 border,
  4px radius, 10px font, 22px height — matching makeSmallValueSlider
- Hide native arrow with appearance:none and add custom SVG chevron
- Center text edge-to-edge using text-align-last:center
- Options now share the same 10px font size as the selected value
- Replace inline select creation in rebuildPanel with makePanelDropdown

Closes #40
2026-04-28 14:58:03 -04:00
Mehdi Chaid ba8bc6ba89 Fix dropdown triangle visibility and remove right-click behavior
- Extract loadOptions() to fetch flake metadata in the background on init
- Call loadOptions() immediately so triangle button shows for flakes with options/loras
- Remove right-click handler that was used as a workaround

Closes #39
2026-04-28 14:55:48 -04:00
Mehdi Chaid 7f63eb0a95 Redesign Load Existing picker with search bar and thumbnail grid
- Replaces file-browser-based load picker with a dedicated overlay
- Shows thumbnail grid with cover images (background-size:cover)
- Search bar filters flakes by name in real time
- Click to select, Cancel / Select buttons in footer

Closes #32
2026-04-28 14:05:54 -04:00
Mehdi Chaid d3460dffdc Fix drag-to-reorder for optional fields in flake edit overlay
- Add proper dragstart/dragover/drop/dragend handlers to field drag handles
- Visual drop indicator shows between fields during drag
- Reorders activeFields array and re-renders on drop

Closes #36
2026-04-28 14:03:56 -04:00
Mehdi Chaid e6ac25c62a Add triangle toggle for URL fields in Preset and LoRA editors
- Model Preset: checkpoint URL hidden by default, toggle with triangle button
  next to Checkpoint label. Blue link icon appears when URL is populated.
- Flake LoRA: replace [...] button with triangle toggle. Header shows LoRA name
  and blue link icon when URL is populated. Full URL no longer shown in header.

Closes #33, closes #34
2026-04-28 14:02:34 -04:00
Mehdi Chaid e18f75df38 Support multiple LoRAs per flake with name, URL, and strength
Backend:
- Add LoraEntry dataclass with name, url, path, strength
- Flake dataclass now has loras[] list; legacy lora_path/strength kept for compat
- _flake_from_raw parses both new multi-LoRA and legacy single-LoRA formats
- resolve() applies multi-LoRA strength overrides from grid entries
- full_flake_node.py applies all LoRAs in order

Frontend:
- Flake edit modal: each LoRA gets its own section with name, URL, path picker,
  strength slider. +Add LoRA button to add more. [...] button edits name/URL.
- Grid dropdown: shows one strength slider per LoRA, labeled with LoRA name
- Grid entries store loras[] array of strengths for overrides
- Backward compatibility: old entries with single strength auto-converted

Closes #30
2026-04-28 13:15:36 -04:00
Mehdi Chaid 46da579d5a Add cover image support for Model Presets
- Backend: add save_preset_cover, read_preset_cover, _preset_cover_path helpers
- Backend: add /flakes/preset_cover GET/POST endpoints
- Frontend: add cover image upload box in preset edit modal
- FlakeModelPreset node: displays preset cover image under the dropdown
- FlakeModelCombo grid items: use preset cover as background with dark overlay

Closes #26
2026-04-28 12:56:13 -04:00
Mehdi Chaid c85bd9e149 Implement Python-backed file browser for correct base paths
- Add /flakes/browse API endpoint that returns directory listings
  filtered by file type (checkpoints, loras, flakes)
- Build custom file browser overlay in JavaScript
- Replace all browser-native file pickers with the Python-backed browser:
  - Checkpoint selection defaults to models/checkpoints/img/
  - LoRA selection defaults to models/loras/img/
  - Load Existing defaults to models/flakes/img/
- Remove unused createFilePicker helper

Closes #29
2026-04-28 12:53:24 -04:00
Mehdi Chaid 99ffab6640 Fix drag indicator position and add rightmost drop target
- Replace inset box-shadow with absolutely positioned indicator at left:-3px
  so the blue line appears in the gap between items rather than on the item
- Add dragover/drop handlers to the Add block for dropping after the last item
- Clear all indicators on drag end

Closes #28
2026-04-28 12:47:39 -04:00
Mehdi Chaid 24e4323265 Fix LoRA strength slider missing in grid dropdown and has_lora detection
- Update has_lora flag after editing/saving a flake (both defaultUpdated and saved cases)
- Update has_lora after overriding pending changes to disk
- Fix incorrect lora_path field name: raw YAML uses 'path', not 'lora_path'

Closes #27
2026-04-28 12:43:53 -04:00
Mehdi Chaid 2a9d475f46 Add checkpoint URL field to Model Preset
- Added checkpoint_url to ModelPreset dataclass and load/save
- Added optional URL input field in the preset edit overlay
- Defaults to empty string

Closes #25
2026-04-28 12:40:39 -04:00
Mehdi Chaid f030f6fe98 Add Output Filename Stem support connected to Save Image filename_prefix
- Model Preset initializes filename prefix with <PresetName>/
- New optional 'Output Filename Stem' field in flakes editor
- FlakeStack collects stems from all flakes and builds prefix:
  - Folder stems (containing '/') are appended to path
  - Date folder <YYYY-MM-DD> inserted after last folder stem
  - Filename starts with <HH-MM-SS> followed by _ separated file stems
- FlakesGenerationData converter outputs filename_prefix as 6th pin

Closes #24
2026-04-28 11:44:52 -04:00
Mehdi Chaid aba0f00ff5 Add file pickers for checkpoint, LoRA, and load existing
- Checkpoint field in preset editor now opens a file picker filtered to .safetensors
- LoRA field in flake editor now opens a file picker filtered to .safetensors
- Load Existing now opens a file picker filtered to .yaml/.yml
- Each picker attempts to map the selected file name back to the backend's full path
- Manual text entry is still available via a small '...' button next to each picker

Note: Browsers do not allow setting the default directory of a file picker for security reasons.

Closes #18, closes #20, closes #22
2026-04-28 11:30:23 -04:00