Easy Gen had no way to stop a run — the only exit was the ComfyUI queue. Adds
the same "■ Interrupt" control the Cutting Room's player readout uses (shared
.gen-interrupt styling), living inside the progress panel so it exists only
while there is something to stop.
ComfyUI records an interrupted prompt in history as status_str "error" with no
media, which the status endpoint cannot tell apart from a real crash — so watch()
remembers that the stop was asked for and reports "Generation stopped." instead
of "Generation failed.", while still showing any partial media the run wrote.
A failed interrupt call re-enables the button and says so rather than leaving a
dead control over a run that is still going.
Co-Authored-By: Claude <noreply@anthropic.com>
Follow-up to the previous commit, per review:
- the panel is no longer docked into Easy Gen's main screen — the "$ Variables"
button now sits in the prompt bar (next to Upload/Gallery, not pinned to the
header) and opens a modal window, same shell as the Gallery picker
- value fields are auto-growing textareas instead of one-line inputs, in the
Cutting Room's Composer as well: a long phrase was impossible to edit in a
single-line field. Height is measured from scrollHeight with the border-box
borders added back, re-fit once after layout (scrollHeight reads 0 before it)
- fully-empty rows are dropped on persist, so an accidental "Add variable" click
never sticks to the project (the row stays on screen until it's filled in —
the open window keeps its own working copy for exactly this reason)
Co-Authored-By: Claude <noreply@anthropic.com>
Ports the Editor Composer's $variables to Easy Gen: a "$ Variables" toggle in
the header opens a collapsible name/value editor docked above the prompt bar.
Same project.variables field the Editor writes, so nothing backend-side is new —
movie_editor/server.py already forwards it on every generate and Studio resolves
it dead-last inside refine_v2 (after shortcut expansion AND after the scene
split), which is what makes a $var work inside a shortcut's replacement while a
value containing a comma or trigger word can never move a scene cut.
- easy_store: projectVariables/setProjectVariables (leading $ stripped on store)
- easy_variables.js: rows + Add/Remove, count badge, live hint for undeclared
names and self-referencing loops (cycle detection mirrors resolve_variables)
- rows rebuild only on add/remove/project-change, so typing never loses focus
Co-Authored-By: Claude <noreply@anthropic.com>
Mirrors mediabrowser.js's card pin button in the Editor: a 📌 button on
each image thumbnail (chain-sampler pipelines only) toggles
continuity_settings.identity_pin_ref, re-enabling auto_enabled if it was
off (a pin does nothing with auto continuity disabled). Same setting as
Engine settings > Continuity > Identity pin, just reachable without
leaving the Gallery. Verified both surfaces read/write the same
continuity_settings and stay in sync.
Easy Gen shipped shortcuts/transitions and multi-scene splitting with no way
to load a shortcut/transition JSON library, no path to Engine Settings
(blocking Generate on stale continuity media refs, no Best-FaceID toggle),
no explicit Save, and no way to reuse an already-uploaded file as an anchor.
- Shortcut/transition JSON import/export in the Shortcuts settings section.
- Full Engine Settings (Studio/Chain Sampler/Continuity/Best-FaceID) now
loads via the same frontend-fallback as autocomplete.js, backed by new
patchProject/setSamplerInput*/setStudioInput*/mediaBin support in
easy_store.js. Removed the now-duplicate Refinement key field from the
slim Generation panel.
- New Gallery picker (easy_gallery.js) to apply prior uploads as the anchor.
- Explicit Save button with Saving…/Saved feedback.
Preview now shows the uploaded image/video (badged "Uploaded source")
when there's no generated result yet, or the generated result itself
with a corner ✕ to dismiss it and reveal the upload underneath.
Fixed two real bugs found while testing this:
- Upload never actually attached to the scene: POST /media returns
{media: [...]} (a list, for multi-file support), but app.js read the
response as if it were the media object itself.
- A save-ordering race could silently lose an edit: two overlapping
save() calls could land on the server out of order, letting an
older save clobber a newer one. save() now serializes through one
queue in easy_store.js, always reading live project state.
- CSS: .easy-preview-close's unconditional display:flex was beating
the hidden attribute (equal specificity); added an explicit
[hidden] override.
Easy Gen is a new Fooocus-style frontend at /funpack/easy — big preview,
one prompt box, Upload, Generate, and an Advanced settings panel — built
entirely on the Movie Editor's existing project format and API (no new
backend endpoints), so projects stay interchangeable between the two UIs.
The Hub at /funpack links to both UIs and surfaces version/branch/commit
plus an Update/Restart action reusing the Editor's git_update.py flow.
Startup now prints full host:port URLs for all three (Hub, Editor, Easy
Gen) via a new config.comfy_display_url() helper.
Also: settings_window.js's About section now labels itself via
window.FunPackAppName instead of hardcoding "Cutting Room", and Easy
Gen's boot-error banner accumulates distinct errors instead of
overwriting, so a cascading failure (e.g. dom.js not loading) surfaces
its root cause instead of just the last script in load order.