Saving a character, object, or scene reused an existing name and
overwrote that preset without asking. Updating the preset already
linked to the region still saves directly.
style["style"] raised when the value was not a dict, and a non-string
overview did the same on strip. A style object is unchanged. A bare
kind string still selects that style, with its description left blank.
Anything else omits the style block.
The editor accepts 64-16384 and snaps to a multiple of 8, so 1920x1080
is easy to enter. The open model needs multiples of 16, from 256 to 2048,
at an aspect ratio of at most 6:1. The size fields show that rule and do
not change the numbers. The spinner steps by 16.
A number or other non-string description reached the canvas line wrap,
which expects a string, and the redraw stopped. Labels, copies, and
loaded presets keep finite numbers as text and drop anything else.
input[type=color] only accepts #rrggbb. A pasted #fff or other shorthand
was given to it unchanged, and the picker then opened on black. Palettes
are stored as the uppercase #RRGGBB colors Ideogram 4 keeps, at most five
per element and sixteen for the style.
The store API already removed entries, but the editor never called it, so
a bad preset stayed in the library. Load dialogs can delete one after
confirmation. A region that pointed at a deleted character or object
drops that link.
Shift-click and double-click preferred the active region when boxes
overlapped, so the region drawn on top could not be toggled or edited.
Both now follow paint order. Dragging still prefers the active handles.
A connected import that was not valid JSON was dropped with no console
line, so the prompt quietly stayed on the editor caption. Non-objects
are reported the same way. A JSON object is still the prompt, and the
console names a missing compositional_deconstruction, background, or
elements list, which Ideogram 4 requires. A leading byte-order mark is
ignored.
Preview BG Update opened every frame as RGB. Pillow rejects that mode
for a four-channel image, a single-channel image, or a plain height-width
array, so the save stopped and the canvas never updated. Those frames are
converted to RGB first. Alpha is composited onto black, which is what the
editor draws the preview over.
Choosing source dimensions or an aspect ratio did nothing while scale mode
was stretch, which is the default. That choice now fits the source layout.
Don't care still stretches, and anchor modes still pin the fit.
A boolean palette or a non-string description raised while building the
caption or the preview. Those values are dropped or turned into text.
Short hex colors use the expanded color in the preview.
Style tooltips said a blank descriptor is omitted. It is sent as an empty
string, which is what the caption schema requires for those keys.
A failed GET /byae/ideogram/stores was caught and replaced with empty
buckets, so Load told the user there were no saved scenes. The request
error now reaches the existing alert, and an empty library is reported
only when the server actually returns one.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: AE <by-ae@users.noreply.github.com>
A bucket file that parsed as a JSON array or other non-object was treated
as empty and then overwritten on the next save, so the previous contents
were gone. Those files are now moved aside like invalid JSON. A backup
created in the same second no longer replaces an existing one.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: AE <by-ae@users.noreply.github.com>
A region stored with numeric strings, NaN, a boolean, or a huge finite
value raised from round() while building the Ideogram bbox or the preview,
so one bad box failed the whole node. Those coordinates are now omitted
from the caption and the preview, and numeric strings still convert.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: AE <by-ae@users.noreply.github.com>
Ctrl+V only clamped the origin, so a region near the edge kept its size and
extended past the canvas. Loading many characters did the same along the
0.04 diagonal. Paste now uses the same inside-canvas nudge as scene add,
and loads after the 17th tile a grid that still fits.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: AE <by-ae@users.noreply.github.com>
The per-bucket lock was inserted without synchronization. Two first
writers could take different locks and overwrite each other's preset
file. Lock creation now happens under a guard lock.
Co-authored-by: AE <by-ae@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
test_store replaced the folder_paths mock after store.py had imported it.
Route tests then configured the replacement, and store writes went to a
MagicMock path that had been committed. Both suites now share the mock
from conftest and land files in a temp directory.
Co-authored-by: AE <by-ae@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Additive scene load nudged each region further than the one before it, so
a saved composition was sheared. Every region now moves by the same offset
and is clamped back inside the canvas.
Co-authored-by: AE <by-ae@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
The caption verifier accepts only uppercase #RRGGBB, at most 16 style
colors and 5 per element. Shorthand #RGB is expanded, other values are
dropped, and a null palette no longer crashes prompt assembly.
Co-authored-by: AE <by-ae@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Pasted captions with swapped or non-numeric bbox values produced negative
or NaN regions, so the editor could not select them. Coordinates are now
swapped and clamped to the 0-1000 range from the Ideogram 4 caption schema,
and unreadable bboxes keep the non-overlapping grid slot for that element.
Saved regions with NaN coordinates are dropped on restore.
Co-authored-by: AE <by-ae@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Preview BG Update logged save and notify failures only when BG_DEBUG was
set, so the console stayed quiet while the README told users to look there.
Warnings now print for a missing image, an empty or invalid guid, a tensor
that cannot be converted, a disk write error, and a failed editor push.
Co-authored-by: AE <by-ae@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
When importing captions with missing/invalid bbox data, elements are now
arranged in a 4-column grid (row/column layout) instead of a diagonal
pattern that overlapped after 6 elements.
- Change fallback positioning from modulo-6 diagonal to row/column grid
- Update both Python backend and JavaScript editor
- Add comprehensive test for 12+ elements with no overlap
- Fixes visual collision when pasting captions with many unbounded regions
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
- Add MAX_PAYLOAD_SIZE constant (10 MB) to prevent memory exhaustion
- Validate store names against path traversal and special characters in routes layer (defense in depth)
- Check Content-Length header and body size before processing
- Return HTTP 413 for oversized payloads
- Add comprehensive test coverage for validation edge cases
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
- Allow Unicode letters/numbers in preset names (e.g. 角色, Персонаж, Émilie)
- Add thread-safe locking per bucket to prevent race conditions during concurrent writes
- Use mkstemp() for atomic temp file creation to avoid tmp file name collisions
- Add tests demonstrating the bugs and verifying the fixes
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
- Test corrupt JSON creates backup and returns empty bucket
- Test corrupt file does not affect other buckets
- Test save works after corrupt file recovery
- Test DELETE success, 404 not found, invalid bucket/name 400
- All existing tests continue to pass
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Implement 10 unit tests covering:
- Name validation (valid and invalid patterns)
- Save, load, and delete operations
- Multiple entries and overwrites
- Empty buckets and non-existent entries
- Invalid bucket names
- Persistence across reloads
Tests use unittest (stdlib) and mock folder_paths dependency,
ensuring the store logic is reliable without ComfyUI runtime.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>