Commit Graph

247 Commits

Author SHA1 Message Date
c9bcc735f4 Change refresh input from INT to combo dropdown (off/on)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:29:30 +01:00
dc8f44f02b Add refresh input to ProjectLoaderDynamic to force re-fetch
Changing the refresh value triggers the node to re-fetch keys from
the API, picking up any new or modified fields in the data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:27:51 +01:00
2a6b4f5245 Add mode integer field above sequence number in batch cards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 01:07:09 +01:00
60d1162700 Fix async callbacks: make rename/change_path directly async
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:42:00 +01:00
204fc4ea85 Add rename for sequences and projects, per-sub color cycling, project path editing
- Sequences: add rename button with name shown in expansion header
- Subsequences: cycle through 6 distinct border colors by sub-index
- Projects: add rename and change path buttons with DB methods

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:40:35 +01:00
033b3415c2 Merge branch 'feature/sqlite-project-db' 2026-03-01 00:32:07 +01:00
2ccc3821d6 Add visual distinction for subsequence cards with teal border
The subsegment-card CSS class was not being applied to subsequence
expansion items. Add the class conditionally and include the teal
accent CSS rules with a 6px left border.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:31:00 +01:00
187b85b054 Clean up: remove unnecessary info.outputs logic, set label on reused slots
The actual fix was setting slot.label alongside slot.name. Reverted
onConfigure to read from widget values (which work correctly) and
ensured label is set on both new and reused output slots.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:12:30 +01:00
a0d8cb8bbf Fix: set output label alongside name for LiteGraph rendering
LiteGraph renders slot.label over slot.name — we were updating name
but the display uses label.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:10:50 +01:00
d55b3198e8 Fix output names not surviving page refresh in ProjectLoaderDynamic
Read output names from info.outputs (serialized node data) instead of
hidden widget values, which ComfyUI may not persist across reloads.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:43:34 +01:00
bf2fca53e0 Remove JSONLoaderDynamic, handled by ComfyUI-JSON-Dynamic extension
The separate ComfyUI-JSON-Dynamic extension provides the same node.
Removes json_loader.py, web/json_dynamic.js, and their tests. Only
ProjectLoaderDynamic remains in this extension.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:18:39 +01:00
5b71d1b276 Fix output name persistence: use comma-separated like reference impl
JSON.stringify format for hidden widget values didn't survive ComfyUI's
serialization round-trip. Switch to comma-separated strings matching
the proven ComfyUI-JSON-Dynamic implementation. Remove properties-based
approach in favor of the simpler, working pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:11:04 +01:00
027ef8e78a Fix ProjectLoaderDynamic output names lost on page reload
Hidden widget values for output_keys/output_types were not reliably
restored by ComfyUI on workflow reload. Store keys/types in
node.properties (always persisted by LiteGraph) as primary storage,
with hidden widgets as fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:04:14 +01:00
86693f608a Remove 9 redundant JSON loader nodes, keep only JSONLoaderDynamic
JSONLoaderDynamic auto-discovers keys at runtime, making the hardcoded
Standard, Batch, and Custom nodes unnecessary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:36:33 +01:00
615755ba44 Revert "Remove 9 redundant JSON loader nodes, keep only JSONLoaderDynamic"
This reverts commit 4b09491242.
2026-02-28 22:36:25 +01:00
4b09491242 Remove 9 redundant JSON loader nodes, keep only JSONLoaderDynamic
JSONLoaderDynamic auto-discovers keys at runtime, making the hardcoded
Standard, Batch, and Custom nodes unnecessary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:33:51 +01:00
4b5fff5c6e Improve ProjectLoaderDynamic UX: single node, error feedback, auto-refresh
Remove 3 redundant hardcoded nodes (Standard/VACE/LoRA), keeping only the
Dynamic node. Add total_sequences INT output (slot 0) for loop counting.
Add structured error handling: _fetch_json returns typed error dicts,
load_dynamic raises RuntimeError with descriptive messages, JS shows
red border/title on errors. Add 500ms debounced auto-refresh on widget
changes. Add 404s for missing project/file in API endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:16:08 +01:00
d07a308865 Harden ROLLBACK against I/O errors in transactions
If the original error (e.g., disk full) also prevents ROLLBACK from
executing, catch and suppress the ROLLBACK failure so the original
exception propagates cleanly and the connection isn't left in a
permanently broken state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:44:12 +01:00
c4d107206f Fix 4 bugs from third code review
- Fix delete_proj not persisting cleared current_project to config:
  page reload after deleting active project restored deleted name,
  silently breaking all DB sync
- Fix sync_to_db crash on non-dict batch_data items: add isinstance
  guard matching import_json_file
- Fix output_types ignored in load_dynamic: parse declared types and
  use to_int()/to_float() to coerce values, so downstream ComfyUI
  nodes receive correct types even when API returns strings
- Fix backward-compat comma-split for types not trimming whitespace:
  legacy workflows with "STRING, INT" got types " INT" breaking
  ComfyUI connection type-matching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:38:37 +01:00
b499eb4dfd Fix 8 bugs from second code review
HIGH:
- Fix JS TypeError on empty API response: validate keys/types are arrays
  before using them; add HTTP status check (resp.ok)
- Fix BEGIN IMMEDIATE conflict: set isolation_level=None (autocommit) on
  SQLite connection so explicit transactions work without implicit ones

MEDIUM:
- Fix import_json_file non-atomic: wrap entire operation in BEGIN/COMMIT
  with ROLLBACK on error — no more partial imports
- Fix crash on non-dict batch_data items: skip non-dict elements
- Fix comma-in-key corruption: store keys/types as JSON arrays in hidden
  widgets instead of comma-delimited strings (backward-compat fallback)
- Fix blocking I/O in API routes: change async def to def so FastAPI
  auto-threads the synchronous SQLite calls

LOW:
- Fix missing ?. on app.graph.setDirtyCanvas in refreshDynamicOutputs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:32:35 +01:00
ba8f104bc1 Fix 6 bugs found during code review
- Fix NameError: pass state to _render_vace_settings (tab_batch_ng.py)
- Fix non-atomic sync_to_db: use BEGIN IMMEDIATE transaction with rollback
- Fix create_secondary() missing db/current_project/db_enabled fields
- Fix URL encoding: percent-encode project/file names in API URLs
- Fix import_json_file crash on re-import: upsert instead of insert
- Fix dual DB instances: share single ProjectDB between UI and API routes
- Also fixes top_level metadata never being updated on existing data_files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:25:31 +01:00
6b7e9ea682 Port dynamic node improvements from ComfyUI-JSON-Dynamic
- Deferred output cleanup (_configured flag + queueMicrotask) to prevent
  breaking links when other nodes (e.g. Kijai Set/Get) resolve outputs
  during graph loading
- file_not_found error handling in refresh to keep existing outputs intact
- Fallback widget sync in onConfigure when widget values are empty but
  serialized outputs exist

Applied to both json_dynamic.js and project_dynamic.js.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:15:56 +01:00
c15bec98ce Add SQLite project database + ComfyUI connector nodes
- db.py: ProjectDB class with SQLite schema (projects, data_files,
  sequences, history_trees), WAL mode, CRUD, import, and query helpers
- api_routes.py: REST API endpoints on NiceGUI/FastAPI for ComfyUI
  to query project data over the network
- project_loader.py: ComfyUI nodes (ProjectLoaderDynamic, Standard,
  VACE, LoRA) that fetch data from NiceGUI REST API via HTTP
- web/project_dynamic.js: Frontend JS for dynamic project loader node
- tab_projects_ng.py: Projects management tab in NiceGUI UI
- state.py: Added db, current_project, db_enabled fields
- main.py: DB init, API route registration, projects tab
- utils.py: sync_to_db() dual-write helper
- tab_batch_ng.py, tab_raw_ng.py, tab_timeline_ng.py: dual-write
  sync calls after save_json when project DB is enabled
- __init__.py: Merged project node class mappings
- tests/test_db.py: 30 tests for database layer
- tests/test_project_loader.py: 17 tests for ComfyUI connector nodes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:12:05 +01:00
0d8e84ea36 Add .gitignore with worktrees, pycache, pytest_cache
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 20:59:39 +01:00
e2f30b0332 Color graph nodes by branch for visual distinction
Each branch gets a unique subtle tint (grey, blue, purple, coral,
teal, sand) so sub-branches are visually distinguishable. HEAD
(yellow) and branch tip (green) colors still take priority.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 20:22:45 +01:00
24f9b7d955 Fix graph interactivity: use querySelector instead of NiceGUI DOM ID
The c{id} DOM ID pattern was wrong. Use document.querySelector with
the timeline-graph class instead, with retries until g.node elements
are present in the DOM.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:27:00 +01:00
d56f6d8170 Fix graphviz crash: use polyline splines instead of ortho
splines=ortho triggers a trapezoid-table overflow assertion in
graphviz's dot layout engine on complex graphs. polyline gives
similar angled edges without the crash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:21:43 +01:00
f2980a9f94 Fix graph: NiceGUI blocks script tags in ui.html()
Move JS back to ui.run_javascript() with retry-based DOM lookup
using NiceGUI's element ID (c{id}). CSS stays inline via style tag.
Retries up to 10 times at 50ms intervals to handle Vue async render.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:20:32 +01:00
4e3ff63f6a Fix graph interactivity: embed JS/CSS inline in HTML
Previous approach used ui.run_javascript with getElement() which
failed due to Vue rendering timing. Now embeds the script and style
directly inside the HTML content so there are no DOM lookup or
timing issues — the script runs inline when parsed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:19:26 +01:00
6e01cab5cd Fix graph interactivity: use NiceGUI element ref and requestAnimationFrame
The click handlers weren't attaching because getElementById couldn't
find the container — Python's id() generated IDs that didn't survive
NiceGUI's DOM rendering. Now uses getElement() with the NiceGUI
element ID and defers JS via requestAnimationFrame to ensure the
DOM is ready.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:15:56 +01:00
16ed81f0db Fix tiny graph: keep SVG natural size, scroll on overflow
Stop replacing the SVG's width/height attributes — this was shrinking
the graph to fit the container. Instead keep graphviz's native pt
dimensions and let the scroll container handle overflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:14:25 +01:00
d98cee8015 Fix timeline graph height: remove invalid SVG height="auto"
Drop the fixed height attribute entirely instead of setting it to
"auto", which SVGs don't support. The viewBox attribute handles
proportional scaling when only width="100%" is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:11:03 +01:00
2ebf3a4fcd Interactive timeline graph: click nodes to select in node manager
Add click-to-select functionality to the graphviz SVG timeline graph.
Clicking a node highlights it with an amber border, auto-switches the
branch selector, and updates the node manager panel. The SVG is now
responsive (100% width, scroll container) instead of fixed-size.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:06:13 +01:00
a4cb979131 Remove stale Streamlit references from comments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:18:37 +01:00
9a3f7b7b94 Remove old Streamlit UI files superseded by NiceGUI migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:17:38 +01:00
d8597f201a Merge nicegui-migration: full NiceGUI web UI 2026-02-27 22:16:34 +01:00
8911323832 Branch-grouped navigation for timeline node manager
Replace flat dropdown with branch selector showing node counts,
scrollable node list with HEAD/tip badges, and inline actions panel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:15:56 +01:00
af5eafaf4d Right-align path inputs to show filename instead of directory prefix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 00:02:14 +01:00
29750acf58 Match Shift button height to input field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:28:35 +01:00
da789e68ad Two-column VACE layout, inline mode reference button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:26:45 +01:00
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