Commit Graph
14 Commits
Author SHA1 Message Date
digital-garbageandClaude Opus 5 5aac3cc5c1 Easy Gen: re-attach to a running generation after a page reload
Easy Gen had no equivalent of the Cutting Room's reconnect-after-reload: reloading
mid-run left Generate re-enabled with no Interrupt and no progress, while the run
carried on server-side.

Nothing was missing on the backend. Easy Gen queues through the Editor's own
/generate route, so its prompts already carry the editor client_id + funpack run
identity, already come back from GET /api/active, and api.js already exposed
active(). Easy Gen simply never asked.

app.js gains reattachRunning(), run after the project is restored on boot:
- Run targets the loaded project -> full re-attach through the existing
  preview.watch(), so the result still lands in the preview when it finishes.
- Run targets something else (typically a montage queued from the Cutting Room)
  -> preview.monitor(), a new queue watcher over /api/active that shows progress
  and Interrupt without claiming the output. It deliberately does NOT switch
  projects out from under the user to take ownership of a foreign run.
- Loops while further runs are queued behind the running one, so Generate stays
  blocked until the queue drains.

Also fixes a live-run bug found on the way: render() ran on every store notify
(health poll every 15s, every prompt keystroke) and unconditionally set
generateBtn.disabled = !project — re-enabling Generate underneath a generation
that was still going. Both paths now go through one setGenerating() flag, which
render() respects, and a project switch mid-run no longer tears down the poll.

preview.js: watch() takes an optional `note` for the initial label so a re-attach
says "Reconnected after reload" instead of "Starting…"; the Interrupt wiring is
shared between watch() and monitor() as _armStopButton().

Verified in the local ComfyUI: page boots clean (only ComfyUI's own pre-existing
console errors), /api/active is polled on boot, monitor() stays pending with an
armed Interrupt while a job reports running and resolves + hides when it leaves
the queue, and Generate survives a store notify. The full-reattach branch reuses
the already-validated preview.watch() path but could not be exercised end to end
locally, since a real run needs the rental GPU.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 12:37:18 +03:00
digital-garbageandClaude 3222fbcb31 Easy Gen: Interrupt button on the progress panel
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>
2026-07-26 20:22:48 +03:00
digital-garbageandClaude 8e9c0479a8 Variables: own window in Easy Gen, auto-growing value fields in both UIs
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>
2026-07-26 20:18:15 +03:00
digital-garbageandClaude 70cd015219 Easy Gen: prompt $name variables panel
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>
2026-07-26 20:11:38 +03:00
digital-garbage f1a376e286 Remove dead "Seed" field from Easy Gen settings; bump to 3.4.0
The Generation panel's Seed field was bound to Project.seed, a legacy field
(movie_editor/backend/timeline.py:562) that nothing in generation reads —
the real seed resolution (server.py's _resolve_run_seed) only ever reads
sampler_inputs.seed, which already defaults to random when unset. The field
always showed "1" and editing it had zero effect, reading as "seed is
stuck, not randomized" when generation was in fact already randomizing
correctly via the real (and already-present) Seed control under Engine ▸
Timing & Seed. Removed the dead field; the settings hint now points there.

Also bumps pyproject.toml to 3.4.0 and adds the CHANGELOG entry for this
session's Easy Gen work (shortcut/transition import, Engine settings, Save/
Gallery/Export buttons, continuity pin, and the bypass/state-sync/
autoplay/filename fixes), ahead of tagging the release on main.
2026-07-24 12:19:49 +03:00
digital-garbage fadfc9626d Add continuity pin button to Easy Gen's Gallery
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.
2026-07-24 11:47:38 +03:00
digital-garbage 99c7dd5ba6 Add project Export button to Easy Gen
Easy Gen's "Save" persists into FunPack's own project store on that
machine, same as the Editor's autosave — it was never a way to move a
project between machines. The backend route for that (download the actual
.funpack_project.json, re-importable via "Load Project File...") already
existed and easy_gen/frontend/api.js already had the URL helper, but no
button anywhere called it, unlike the Editor's File > "Save Project File...".
Added an "Export..." button next to Save that flushes a save first, then
downloads the project file.
2026-07-24 11:29:58 +03:00
digital-garbage 6a58b35f6f Fix Easy Gen silently reverting Models & Pipeline edits; two smaller fixes
Root cause of "bypass I just disabled is still bypassed after reopening
settings": models.js saves bypass/expose/widget edits straight to the
server via its own PUT /projects/{id}/models, entirely independent of Easy
Gen's state.project. Any later save() (prompt debounce, the Save button, an
upload) sent the STALE in-memory project.models back to the server and
silently clobbered whatever was just changed there — same class of bug the
Editor's store.js already guards against by syncing state.models into
project.models before every autosave commit, which Easy Gen never got.
Fixed by refetching the authoritative models config at the top of every
save() call. Verified live: toggling bypass via the Models API then calling
Store.save() no longer reverts it.

Also:
- preview.js: video elements used the `autoplay` attribute, which makes the
  browser call .play() internally with no promise we can catch. Replacing
  the element before that settles (e.g. picking a new Gallery item) surfaced
  as an unhandled "fetching process...aborted" rejection banner. Now calls
  .play() ourselves so we own (and can catch) the promise.
- server.py: the /result route had no Content-Disposition, so "Save Video
  As" fell back to a generic name derived from the URL path ("result.mp4")
  every time. The underlying render file is already uniquely named per run
  and already lives in ComfyUI's temp dir (cleared on restart) — just
  wasn't surfaced to downloads. Now sets Content-Disposition with the real
  per-run filename on all three /result response paths.
2026-07-24 11:23:23 +03:00
digital-garbage c2d1257a8e Easy Gen: add Log button, stop preview auto-resuming, hide inert eye buttons
- Add the Cutting Room's "Log" button/panel to Easy Gen (log.js is already
  fully self-contained and hits the same shared /api/log route Easy Gen's
  api.js already calls) — just needed the script tag and a .menubar-right
  wrapper for it to mount into.
- Fix: any Store notify (health poll every 15s, prompt debounce) rebuilt the
  preview's <video>/<img> from scratch, reapplying autoplay/loop and silently
  resuming anything the user had paused. draw() now skips the rebuild when
  the actual content being shown hasn't changed.
- Hide the "expose to editor" eye buttons (both plain widgets and the bypass
  toggle) in Models & Pipeline when running under Easy Gen — there's no main
  editor / per-scene inspector for an exposed control to ever appear in, so
  they were inert clutter that could look actionable and silently do
  nothing. Gated on window.FunPackAppName, same discriminator engine_settings.js
  and sampler_panel.js already use; Movie Editor is unaffected.
2026-07-24 11:02:04 +03:00
digital-garbage cfe606fb95 Force Easy Gen into a rating-free Studio Prompt-only pipeline
Easy Gen has no rating UI and won't get one — so every Engine setting that
is a no-op without a trained refinement key/rated history is now hidden
there (gated on window.FunPackAppName, the existing Easy-Gen discriminator),
not just harder to find: refinement key, value guidance, steer mode,
reference injection, embed/score/output guidance, taste retrieval,
DynaShift, and sampler-panel velocity bias/rescue. A note points users to
the Cutting Room or the ComfyUI graph for the full learned refiner.

Also enforced at the pipeline level, not just the UI: every Easy Gen
generate call now forces the Studio node into "Prompt only" mode and the
rating-gated Chain Sampler knobs off via node_overrides, so a project
edited in the Cutting Room with these enabled still generates plainly when
run from Easy Gen. Movie Editor is untouched — FunPackAppName is unset
there, so every added gate evaluates false.
2026-07-24 10:50:36 +03:00
digital-garbage d4236be5fb Easy Gen: shortcut/transition library import, Engine settings, Save, Gallery
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.
2026-07-24 10:37:40 +03:00
digital-garbage 0191f71606 Add prompt autocomplete, splits, anchor, and shortcut revolver to Easy Gen
The one prompt textarea is now the verbatim "global prompt" and silently
splits into N scenes via the same backend parser the Editor's Composer
uses (POST /projects/{id}/parse) — no per-scene UI is ever shown, and
Generate already runs the whole project as one chain request (no
scene_ids filter), so N scenes still come back as one stitched video.

- easy_store.js: applyGlobalPrompt()/scheduleGlobalPromptApply() port
  the Editor's split+anchor-fold logic (_normalizeGlobalPromptParse,
  _inferSplitMarkers), sequence-guarded against a stale parse response
  racing a newer keystroke. Scene 0 keeps its uploaded source across
  re-splits; scenes 1..N default to "carry" (continue the chain).
  Also added getEditorSetting/setEditorSetting (same localStorage key
  as the Editor) and loadLibraries() (shortcuts + transitions).
- easy_shortcuts_settings.js (new): "Shortcuts" settings section —
  autocomplete + anchor toggles, plus the shortcut revolver (server-side,
  shared with the Editor and with generation regardless of which UI
  queued the run). Skips the Editor's "ideas" bulb and its custom-node
  anchor-guide bypass section, neither relevant here.
- app.js: prompt box now drives scheduleGlobalPromptApply() instead of
  editing scene 0 directly, displays project.global_prompt, and attaches
  ShortcutAutocomplete.

Verified live: multi-scene split + anchor fold match real project data,
upload survives a re-split, autocomplete fires against the real shortcut
library, revolver toggle round-trips, and Generate submits the whole
multi-scene project correctly (fails at the same "missing pipeline
nodes" point as before on this bare dev install — no regression).
2026-07-23 17:27:03 +03:00
digital-garbage fe45c422ce Show uploaded media in Easy Gen preview, with a close/remove button
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.
2026-07-23 16:58:28 +03:00
digital-garbage 9791cb8ccd Add FunPack Easy Gen (simplified single-scene UI) and a /funpack Hub
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.
2026-07-23 16:37:26 +03:00