Commit Graph

207 Commits

Author SHA1 Message Date
79755c286b Move VACE Settings to full-width section below splitter columns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:23:37 +01:00
39a1b98924 Fix history snapshot corruption, missing dir crash, stale batch delete
- Deep-copy node data on restore to prevent edits from mutating
  stored history snapshots
- Guard glob calls against non-existent current_dir
- Read current selection at delete time instead of using stale
  render-time capture

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:11:11 +01:00
d3dbd4645a Remove Promote button (legacy single-file editor feature)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:05:19 +01:00
d795671763 Display LoRA strength with one decimal place (1.0 not 1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:03:56 +01:00
9f141ba42f Fix input sync bugs, improve LoRA UX, and harden edge cases
- Sync dict_input/dict_textarea/LoRA inputs on update:model-value
  (not just blur) to prevent silent data loss on quick saves
- Split LoRA into name + strength fields, default strength to 1.0
- Stack LoRAs one per line instead of 3-card row
- Collapse "Add New Sequence from Source File" into expansion
- Add file selector to Pane A in dual-pane mode
- Clear secondary pane state on directory change
- Fix file radio resetting to first file on refresh
- Handle bare-list JSON files and inf/nan edge cases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:02:24 +01:00
7931060d43 Fix number inputs not syncing to dict until blur
dict_number() only wrote to seq[key] on blur, so changing a value
(e.g. via spinner arrows) and immediately clicking Save could race
the save ahead of the blur on the server. Now also syncs on
update:model-value so the dict is always current.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:49:09 +01:00
3264845e68 Add dual-pane batch processor with independent file state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:41:25 +01:00
fe2c6445ef Constrain main content area to 1200px max-width
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:29:08 +01:00
710a8407d2 Overhaul UI: new color palette, spacing, and visual hierarchy
Replace red accent with amber, add Inter font, introduce 4-level depth
palette via CSS variables, expand padding/gaps, wrap sidebar and content
sections in cards, add section/subsection header typography classes, and
style scrollbars for dark theme. Pure visual changes — no functional or
data-flow modifications.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:27:02 +01:00
97748ab8ff Fix VACE schedule default mismatch introduced in refactor
dict_number() defaulted to 0 while mode_label used default of 1,
causing visual inconsistency when 'vace schedule' key is missing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:01:09 +01:00
b0125133f1 Refactor for readability: declare state attrs, extract helpers, deduplicate
- Declare dynamic attributes (_render_main, _load_file, etc.) in AppState
  dataclass instead of monkey-patching at runtime
- Extract max_main_seq_number() and FRAME_TO_SKIP_DEFAULT in batch tab
- Add commit() closure in _render_sequence_card to deduplicate save/notify/refresh
- Add default param to dict_number(), replace hand-rolled CFG/VACE/custom bindings
- Extract _delete_nodes() helper in timeline to deduplicate single/batch delete
- Split 230-line render_timeline refreshable into 4 focused section helpers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:56:40 +01:00
a8c9a0376d Fix number inputs saving whole numbers as floats in JSON
NiceGUI's ui.number returns float values, so seeds, steps, dimensions
etc. were being stored as floats (e.g. 42.0) instead of integers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:30:20 +01:00
9c171627d8 Fix mass update not refreshing UI after applying changes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:54:12 +01:00
b7a7d8c379 Update README for NiceGUI migration
Update badge, installation instructions, port references, and file
structure to reflect the migration from Streamlit to NiceGUI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:28:46 +01:00
3928f4d225 Fix select options not pushing to browser and remaining shallow copies
- Use set_options() instead of direct .options assignment (3 locations)
  so dropdown changes actually reach the browser
- Wrap res.json() in try/except for non-JSON server responses
- Deep copy in create_batch and promote to match rest of codebase

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:22:40 +01:00
a0d58d8982 Fix multiple bugs found in code review
- save_config calls now pass full config to preserve comfy settings
- Mass update section moved inside refreshable to stay in sync
- Deep copy source data to prevent shared mutable references
- Clipboard copy uses json.dumps instead of repr() for safe JS
- Comfy monitor uses async IO (run_in_executor) to avoid blocking
- Auto-timeout now updates checkbox and refreshes live view UI
- Image URLs properly URL-encoded with urllib.parse.urlencode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:16:28 +01:00
b6f31786c6 Style NiceGUI to closely match Streamlit dark theme
Exact Streamlit colors: #0E1117 background, #262730 secondary,
#FF4B4B primary accent, #FAFAFA text, rgba borders. Match input
styling, border-radius, sidebar width, tab indicators, and
separator colors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:09:00 +01:00
f48098c646 Use splitter for 2-column sequence layout matching Streamlit
Replaces row/col grid with a resizable splitter at 66/34 ratio,
matching the original Streamlit st.columns([2, 1]) layout. Removes
extra card wrapper from sequences to maximize content width.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:38:34 +01:00
3bbbdc827c Fix drawer JavaScript timeout by setting explicit initial value
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:34:41 +01:00
79a47e034e Switch to dark theme to match original Streamlit look
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:33:25 +01:00
d5fbfe765e Fix UI readability and clipping issues
Add page/sidebar background contrast, wrap action button rows,
ensure dark text in inputs, and improve timeline card highlight colors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:30:44 +01:00
f6d5ebfe34 Migrate web UI from Streamlit to NiceGUI
Replace the Streamlit-based UI (app.py + tab_*.py) with an event-driven
NiceGUI implementation. This eliminates 135 session_state accesses,
35 st.rerun() calls, and the ui_reset_token hack. Key changes:

- Add main.py as NiceGUI entry point with sidebar, tabs, and file navigation
- Add state.py with AppState dataclass replacing st.session_state
- Add tab_batch_ng.py (batch processor with blur-binding, VACE calc)
- Add tab_timeline_ng.py (history tree with graphviz, batch delete)
- Add tab_raw_ng.py (raw JSON editor)
- Add tab_comfy_ng.py (ComfyUI monitor with polling timer)
- Remove Streamlit dependency from utils.py (st.error → logger.error)
- Remove Streamlit mock from tests/test_utils.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 10:53:47 +01:00
bdcc05f388 Fix mode-unaware base_length recovery in VACE calculation
The recovery formula now matches the storage formula per mode:
End Extend subtracts only A, Pre Extend subtracts only B.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:24:06 +01:00
31da900502 Add mode-aware VACE frame calculation with 4n+1 snap
- Formula changes per VACE schedule: End Extend uses base+A,
  Pre Extend uses base+B, others use base+A+B
- Snap total to 4n+1 to match VACE sampler
- Show mode name label next to schedule number
- Add mode reference popover with all formulas

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:16:52 +01:00
f8f71b002d Change CFG default to 1.5
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:12:48 +01:00
bc75e7f341 Add CFG input to batch processor UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:10:37 +01:00
6a3b72c035 Remove dead code: unused imports, session state keys, blank lines
- Remove unused `random` import and `KEY_PROMPT_HISTORY` from app.py
- Remove dead session state keys: edit_history_idx, append_prompt, rand_seed
- Clean up extra blank lines in json_loader.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:40:41 +01:00
387d4d874c Remove Single Editor tab (dead code)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:14:09 +01:00
7261f2c689 Change input_a_frames and input_b_frames default to 16
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:12:24 +01:00
2263c3f598 Store vace_length as total (base + input_a + input_b) in JSON
UI shows the base value (vace_length - input_a - input_b) for editing,
saves the computed total back to the JSON.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:11:11 +01:00
7252fa3855 Fix load_dynamic missing output_types parameter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:03:03 +01:00
a747f86daa Persist output types across save/load via hidden output_types widget
Types were lost on workflow reload because only key names were stored.
Now both keys and types are saved in hidden widgets and restored by
onConfigure, so colored connector dots persist without needing Refresh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:16:50 +01:00
f5e242950d Auto-detect output types (INT, FLOAT, STRING) on dynamic node refresh
API route now returns types alongside keys. JS sets output slot type
accordingly, giving correct colored dots and type-safe connections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:11:30 +01:00
dfab5e12ab Rewrite README with SVG diagrams and Dynamic node documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:08:33 +01:00
a08f2676f5 Fix tall node on creation by resizing after removing default outputs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:01:01 +01:00
3255fe76dc Preserve connections on Refresh when keys are added or reordered
Diff new keys against existing outputs instead of remove-all/add-all.
Reuses slot objects for matching key names so links stay connected.
Only disconnects links on keys that were actually removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:00:16 +01:00
0d44944192 Fix dynamic node outputs using LiteGraph removeOutput/addOutput API
Direct array manipulation bypassed LiteGraph's internal slot tracking,
causing output names to show as defaults instead of JSON key names.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:57:06 +01:00
8cc244e8be Add case-insensitive path resolution for Current Path input
Walks each path component and matches against actual directory entries
when an exact match fails on Linux. Widget resyncs to the corrected
canonical path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:52:48 +01:00
e841e9b76b Add JSONLoaderDynamic node with JS frontend for auto-discovered outputs
Dynamic node reads JSON keys and exposes them as outputs automatically
via 32 AnyType slots managed by a JS extension (show/hide/rename).
Includes /json_manager/get_keys API route, bool-safe type handling,
and workflow save/reload support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:47:22 +01:00
a4717dfab6 Add vace_length field, move end_frame out of VACE settings, revert type coercion
- Moved end_frame to main settings area (i2v field, not VACE)
- Added vace_length (default 49) with computed output display
  showing vace_length + input_a + input_b
- Reverted custom param type coercion (ComfyUI handles conversion)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:26:13 +01:00
3718975d99 Add image preview popover for reference and FLF path fields
Shows a clickable eye button next to each image path input that
opens a popover with the image preview when the path is valid.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:49:17 +01:00
40ffdcf671 Clean up DEFAULTS: remove unused settings, add end_frame and transition
Removed steps, cfg, sampler_name, scheduler, denoise, model_name, and
vae_name that were showing as custom parameters. Added end_frame (0)
and transition (1-2) with VACE Settings widgets. Set default
general_negative prompt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:34:21 +01:00
81ecb91835 Fix Clone Next inserting between parent and its sub-segments
When cloning a parent sequence, the new sequence now inserts after the
parent's last sub-segment instead of directly after the parent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 18:34:59 +01:00
e196ad27f5 Update templates to batch-only and remove single file option
Templates now generate batch_prompt_i2v.json and
batch_prompt_vace_extend.json as batch files. Create New JSON
always creates batch files since single mode is deprecated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 17:04:39 +01:00
bd628b062e Clear stale file selector when navigating to empty folder
Removes leftover file_selector and loaded_file state when the current
directory has no JSON files, preventing stale data from persisting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 17:01:50 +01:00
1abae0de22 Fix path navigator using on_change with deferred sync
The inline check caused mismatches between typed and resolved paths.
Now uses on_change callback that always sets _sync_nav_path flag,
so the widget is synced to the canonical current_dir path on the
next rerun before the widget renders.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 17:00:37 +01:00
64472c7850 Fix nav_path_input write-after-widget error on invalid path
Use _sync_nav_path flag to defer the revert to the next rerun, before
the widget is instantiated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:54:52 +01:00
907e7efd68 Fix path navigator by replacing on_change with inline check
The on_change callback had timing issues with Streamlit's session state,
causing user input to be discarded. Now checks the widget value inline
after render and triggers rerun on valid directory change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:53:06 +01:00
0cfe9c9d4b Fix Current Path input reverting on directory change
The nav_path_input was force-overwritten on every rerun, causing
Streamlit to discard user edits before the on_change callback could
process them. Now only syncs on first load or external changes
(favorites). Also resets loaded_file on dir change and reverts
widget on invalid paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:37:53 +01:00
563dba5a0c Fix frame_to_skip shift by caching saved value in session state
The old_fts value was read from the data dict which gets mutated
in-place by widget renders, so on button click rerun delta was always 0.
Now the saved value is captured once per ui_reset_token cycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:39:21 +01:00