1069 Commits
Author SHA1 Message Date
digital-garbageandClaude Opus 4.8 fa3a884528 Merge dev into main — Release 3.1.0
Brings the OpenCut Cutting Room rebuild, Anchor-as-guide, Mixed self-image
guide, autocomplete, and the Scene Builder / character / NormalizingSampler
removals onto main. Tree matches dev exactly (discards the obsolete
cutting_edge README doc link).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v3.1.0
2026-06-21 04:17:13 +03:00
digital-garbageandClaude Opus 4.8 cdc3085ac1 Release 3.1.0
OpenCut-style Cutting Room rebuild, Anchor-as-guide source, Mixed self-image
guide, prompt autocomplete, Composer floating window + file management,
canonical scene splitter, Scene Builder / character / NormalizingSampler
removals. See CHANGELOG.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 04:16:24 +03:00
digital-garbageandClaude Opus 4.8 573e5f26eb README: rename 'Dev and Cutting Edge branches' → 'Dev and other non-main branches'
The cutting_edge branch is gone; generalize the section to cover short-lived
non-main branches without the 'cutting edge' branding, same warning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 04:14:37 +03:00
digital-garbageandClaude Opus 4.8 0624341995 opencut_ui: show the anchor-image picker for Mixed scenes in the inspector
Mixed scenes never rendered an inspector image picker — renderSourceField only
called renderImageSource for eff === "image", even though renderImageSource has a
dedicated mixed branch ("Anchor image (mixed i2v)"). So a Mixed anchor could only
be set by dragging onto the timeline clip, unlike image/anchor_guide. Render the
picker for eff === "mixed" too, giving Mixed the same on-timeline + inspector image
visibility as the other anchor modes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 04:08:00 +03:00
digital-garbageandClaude Opus 4.8 3b1eeee130 opencut_ui: fix autocomplete Tab (trailing space) + orphaned menu in the corner
Two bugs from the Tab update:

1. Tab didn't finish the trigger at end-of-text. The skip-space regex included `$`,
   so when the caret was at the end of the field (the common case) NO trailing space
   was added — the menu then re-opened on the just-accepted trigger (it matches
   itself) and appeared stuck. Drop `$`: always add the space unless a space/delimiter
   already follows.

2. Orphaned menu stranded in the top-left with no way to dismiss it. The menu lives in
   document.body; when a panel re-render removes its host textarea, removal doesn't fire
   blur, so the menu was never cleaned up and a later scroll repositioned it against a
   detached element (rect 0,0 → corner). Now: open() sweeps stray .ac-menu (single menu
   app-wide) and bails if the textarea is detached; refresh()/position() close on a
   detached textarea; and a MutationObserver closes + disconnects when the textarea
   leaves the DOM, so it hides on its own.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 04:08:00 +03:00
digital-garbageandClaude Opus 4.8 c6e5e5f2a5 opencut_ui: Anchor-as-guide keeps the image as a real anchor (timeline + pipeline)
The first cut withheld the anchor_guide image (set_primary=False) to get an
empty latent "for free". That broke real (custom) pipelines: the image vanished
from the timeline and never reached the graph, so a downstream Image Transform
node — which derives width/height from the input image even when i2v is
bypassed — had no input and generation failed.

Corrected model: the image flows into the pipeline like any anchor (copied as
primary -> source_image / image_processing), shows on the timeline, and is
required. The EMPTY LATENT comes from bypassing the i2v node (the value-only
node_overrides), not from withholding the image. On the built-in pipeline there
is no bypassable i2v node, so it runs as a normal i2v anchor + frame-0 guide;
the inspector warns when no i2v node is declared.

- timeline: anchorMediaRef / SRC_ICON / appendSrcBadge show the anchor_guide
  thumbnail + a "guide" badge.
- store: _anchorAvailable / _continuesChainRun treat it as an anchor; drop keeps
  guide mode instead of forcing plain image.
- backend: _prepare_media / scene_anchor_media_refs / _anchor_media_ref /
  source_needs_anchor_media include anchor_guide; removed the now-dead
  anchor_guide_media_refs guide-only copy path (image is a normal anchor now).
- inspector: relabel to "Anchor image (guide mode)", warn when no i2v node set.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 04:00:19 +03:00
digital-garbageandClaude Opus 4.8 2f55814b6c opencut_ui: node search/filter available in every Add-Model mode
The "Filter nodes…" box only showed for "Any node" mode; role-based modes
filled the dropdown directly with no way to search. Now the filter is shown
for any selected model type and applies to role candidates and Any-node alike
(applyFilter drives both paths).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 03:47:42 +03:00
digital-garbageandClaude Opus 4.8 4f153cee99 opencut_ui: Mixed mode also attaches the scene's own image as a frame-0 guide
Mixed scenes carried prior-scene guides but the FIRST scene (nothing prior to
carry) got no guide attention at all — only the i2v anchor. Generalize the
anchor_guide self-image guide path to also cover mixed: each mixed scene's own
image is added as a reinforcing frame-0 guide (strength 0.35), merged on top of
the carried prior guides. Renamed build_anchor_guide_guides ->
build_self_image_guides. Mixed images are already copied as anchors, so guide
refs resolve via funpack_scene_media_refs with no extra media prep.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 03:46:14 +03:00
digital-garbageandClaude Opus 4.8 1a2b4636eb opencut_ui: add "Anchor as guide" scene source (image steers, empty latent)
New scene Source mode: the image is applied as a frame-0 guide via the
existing guide-attention path while the latent fed to the sampler stays empty
(text-to-video). The image is never the i2v anchor, so frame 0 is not locked.

Backend (timeline.py / server.py):
- SceneSource.guide_strength (0..1, per-scene; default 0.35).
- build_anchor_guide_guides() emits a frame-0 self-image guide per anchor_guide
  scene; merge_scene_guide_payloads() overlays it onto continuity/manual stacks.
- anchor_guide images are copied guide-only (set_primary=False) so source_image
  is never wired -> empty latent comes free in the built-in pipeline.
- _apply_node_overrides(): force widget inputs on built-graph nodes from a
  client-supplied node_overrides list (the optional custom-i2v bypass).

Frontend:
- inspector: Source option + guide image picker + strength slider.
- editor_settings: per-browser "Anchor as guide" section — declare a custom
  i2v node and the input/state to force on those runs (value-only). Built-in
  pipeline needs none of this.
- store: sends node_overrides only for runs containing an anchor_guide scene;
  pipeline_caps: anchor_guide is chain-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 03:43:29 +03:00
digital-garbageandClaude Opus 4.8 ac0e4edd37 opencut_ui: roll-up Composer minimize in place + autocomplete finishes on Tab
Minimize now collapses a FloatingWindow to its title bar where it sits (a
window-shade), instead of sending a pill to a bottom-left dock. The button
toggles +/—; double-click the bar also expands. Removed the dock/pill code
and CSS.

Autocomplete accept (Tab/Enter/click) now appends a trailing space so the
trigger is "finished" and the menu doesn't re-open on the just-completed
trigger (it matched itself); skips the space when a space/delimiter follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 03:43:12 +03:00
digital-garbageandClaude Opus 4.8 886a2bb3a9 opencut_ui: fix styled text-overlay crash on newer Pillow (float bbox -> int)
multiline_textbbox() returns float coords on Pillow >= 10, so tw/th flowed into
Image.new() as floats -> "TypeError: 'float' object cannot be interpreted as an
integer" the first time a styled text overlay was exported. Round the bbox coords
to int before using them for sizes and offsets. Surfaced by running the (previously
PIL-skipped) test_render_text_overlay_styled in the ComfyUI venv; all overlay tests
now pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 17:04:50 +03:00
digital-garbageandClaude Opus 4.8 9d69f4bef8 opencut_ui: split_scenes cuts on expansion-keyed transitions (scene-drop fix)
The canonical generation/preview/key splitter (split_scenes) only treated a
shortcut as a scene cut when the shortcut's TRIGGER word was a key in the
transition DB. But split markers are commonly keyed by the EXPANSION phrase: a
"cut" shortcut expands to "Scene cut.", and the split marker is "scene cut.".
So the lookup `custom_map.get(_norm(raw))` missed, the shortcut was treated as
plain content, and NO cut was made — split_scenes returned one scene for
"A cut B cut C" while the verbatim editor split returned three. That disagreement
collapsed the timeline's middle scenes (and would have generated one scene).

Fix: when the trigger word isn't in the DB, also match the shortcut's EXPANSION
(`custom_map.get(_norm(exp))`). The generic "scene <N>" label is still NOT matched
on expansions, so an incidental "scene 2" inside a content shortcut never cuts.
Verified against the user's on-disk cut/qcut defs: split_scenes now agrees with
the verbatim split (2 scenes for cut x2 / qcut x2 / mixed). Added regression tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 17:03:28 +03:00
digital-garbageandClaude Opus 4.8 7ed0717f73 opencut_ui: fix shortcut autocomplete never suggesting in prose prompts
The query was the whole token since the last , ; \n delimiter, and a trigger only
matched if that entire token was a substring of it. Typing a normal multi-word
prompt grew the token past any short trigger, so suggestions never appeared.

Now match TRAILING WORD-RUNS of the token, longest first ("golden ho" before
"ho"), keeping substring matching so "@golden" still matches "golden". The longest
run that hits any trigger wins; its span is what acceptance replaces, so completing
a multi-word trigger can't duplicate words. Verified the matching across start-of-
field, mid-prose partials, post-comma, and no-match prose cases.

Also lifted .ac-menu z-index (9000 -> 99999) so it can never render behind the
Composer floating window when completing in the Compose tab.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 11:22:33 +03:00
digital-garbageandClaude Opus 4.8 247ab84e34 opencut_ui: inline clip reorder controls on the timeline
Reordering was Edit-menu-only (Move Clip Left/Right). Added ◀ ▶ buttons to each
clip's head bar (next to Remove) that call the same moveTimelineClip, disabled at
the ends. Works for both generative and video clips. (Add was already on the
timeline toolbar via + Add → Clip.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 11:12:05 +03:00
digital-garbageandClaude Opus 4.8 a534f8bb6f opencut_ui: hard-remove the character feature (no UI surface remained)
The rebuilt editor never exposed character creation/assignment, so the feature
was vestigial: dead frontend plumbing plus generation branches that only fired
for legacy/imported projects. Removed it wholesale per decision.

Backend:
- Deleted movie_editor/backend/characters.py and the /library/characters routes.
- timeline.py: dropped normalize_character_bible / build_characters_anchor /
  _load_character_map / _scene_character_prefix / character_media_refs_for_project
  and friends. effective_anchor/effective_negative_prompt now return the project's
  manual text; resolve_scene_identity_pin(cs) returns the project-level identity
  pin only. Removed Scene.character_ids and Project.character_bible fields and the
  character_ids fingerprint key.
- Continuity auto-guides keep working off continuity_settings.identity_pin_ref.

Frontend:
- store.js: removed state.characters, the character preview-key plumbing,
  load/save/deleteCharacter, sceneCharacterIds/toggleSceneCharacter, character_ids
  in patch/archive paths and exports.
- timeline.js: dropped clip-char badge rendering; api.js: dropped character routes;
  view_bus.js: dropped chars fingerprint; tour.js: dropped demo characters + copy;
  styles.css: dropped .clip-chars/.clip-char.

Tests: removed test_characters.py and the character-bible timeline tests; added
manual-anchor / manual-negative / project-identity-pin tests. 133 passed, 4 skipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 11:08:48 +03:00
digital-garbageandClaude Opus 4.8 41e0cc48d5 opencut_ui: drop dead .char-* / .plan-* CSS
Both class families had zero JS references in the rebuilt UI. Removed all of
.char-* (character inspector/chips — no surface in the new editor) and the
.plan-* plan-strip styling (plan UI is gone). Kept the two still-live classes
that share neither prefix's full set: .clip-chars/.clip-char (clip badges) and
.clip.off-plan (removed_from_plan marker).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:44:48 +03:00
digital-garbageandClaude Opus 4.8 a9001123bd opencut_ui: Composer file management — Replace/Merge import, Delete-all, Files tab
Composer pt.2 backlog (#6/#7/#8):
- Import now asks Merge (overlay, name-overwrite) vs Replace all (wipe first),
  for both shortcuts and split markers. Backend import_* gain a replace flag;
  routes read ?mode=replace.
- Delete-all buttons clear every shortcut+category / every split marker, via new
  clear_shortcuts / clear_transitions bridge fns + /clear routes.
- New Composer "Files" tab: on-disk file manager over the prompt-library JSONs and
  the refinement-key store (keys + sidecars + value/latent .pt) with size, per-file
  delete, and per-group delete-all. Path-traversal-safe (basename-only, root-checked).
  Deleting library JSONs reloads Shortcuts/Splits so no stale entries linger.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:41:32 +03:00
digital-garbageandClaude Opus 4.8 0dbeadec74 opencut_ui: richer text overlay styling (bold/italic/align/outline/shadow/box)
Centralized text styling in OverlayUI (applyTextCss + textStyleControls) shared by
the program monitor, the Add-text modal, and the inspector. Pillow export renderer
honors every prop (real bold/italic faces or faux stroke/shear).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 01:00:38 +03:00
digital-garbageandClaude Opus 4.8 df3ac62e46 opencut_ui: shortcut autocomplete, Add-shortcut picker, anchor toggle + Editor settings
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 22:57:06 +03:00
digital-garbageandClaude Opus 4.8 a1bf407e39 opencut_ui: fix image-drop anchor, preview stick, t2v removal, full rewiring
1. Image drop → i2v anchor: re-wire S.assignMediaToScene onto the timeline clip
   (it was orphaned when the Plan card, its only caller, was removed).
2. Full rewiring in Full control: nodes.core_producers() now enumerates every
   installed core node's outputs (Studio model/conditioning/sigmas, sampler
   latent/images…), so a custom slot (e.g. a replacement sampler) can source
   them via input_sources. core_graph() tags each output with source_id + lists
   slot consumers; Models shows all core outputs (tappable in Full control).
3. Preview stuck on the media-bin preview ('anchor'): clear the transient
   mediaPreviewId on transport scrub/seek (_seekNow), play (_play), and clip
   selection (selectScene) so the program resumes following the playhead.
4. Remove t2v ('empty') as a selectable scene source; default new scenes to i2v
   anchor. Anchorless scenes still fall back to t2v in the engine.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:07:18 +03:00
digital-garbageandClaude Opus 4.8 114e20ac48 opencut_ui: slim Scene options, Composer polish, managed category list
- Scene properties: 'More editing' → slim 'Scene options'; Frames/FPS hoisted
  to the always-visible body; effects (blur/fade/zoom) dropped here (now applied
  from the timeline + Add → Effects, same scene.effects); source trim, i2v
  guides, and Exclude kept.
- Composer: shortcut editor modal now stacks above the floating window (z-index).
- Composer button restyled to match the neighbouring panel tabs.
- Categories/sub-categories: persisted managed list (nested) in templates.py;
  shortcut editor uses Category/Sub-category dropdowns with inline '+ Add new…'
  mini-modals; Shortcuts '+ Add' is now a dropdown (Shortcut/Category/Sub-category).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 19:53:16 +03:00
digital-garbageandClaude Opus 4.8 1a1e3b5e77 opencut_ui: shortcuts gain Category / Sub-category (for the Compose tab)
- templates.py: persist category + sub_category on each shortcut (normalized,
  free-text; sub-category nests under category).
- Composer shortcut editor: Category + Sub-category inputs; list rows show a
  "category · sub" tag and filter on it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:43:48 +03:00
digital-garbageandClaude Opus 4.8 98a76a94f1 opencut_ui: Composer revamp pt.1 — Compose tab, drop Characters, declutter Properties
- Composer button moves next to the Assets/Preview/Properties tabs (was in the
  menu bar).
- Remove Characters entirely from the UI (Composer tab + the scene inspector's
  character chips). Backend character code left dormant.
- New "Compose" tab hosts the Global prompt (moved out of the inspector); stays
  in sync with the timeline, never clobbers active typing.
- Properties decluttered: drop Video transition, Blend length, Generation split
  marker and "Pause before next clip" from a scene, and "Split before scene 1"
  from the project — these are driven by the global prompt and timeline.
- Swap Import/Export arrows in Shortcuts & Splits (Import ↓ "to me", Export ↑).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:39:39 +03:00
digital-garbageandClaude Opus 4.8 499a68abde opencut_ui: Media Browser (Assets) is now media-only
Strip the five non-media tabs from the left panel — it shows projects + the
media bin and nothing else:

- Characters / Shortcuts / Split markers already live in the Composer window.
- Effects / Transitions are edited per-clip in the Properties inspector
  (Video effects + Outgoing seam), so the preset-apply tabs were redundant.

Removed the orphaned tab renderers and their helpers (editors, modal,
search/filter, characterForm). Updated the welcome tour: the old "Media
libraries / .bin-tabs" step now points at the Composer button, and the
split-marker hint points to the Composer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:24:23 +03:00
digital-garbageandClaude Opus 4.8 a0afb9e906 opencut_ui: borrow OpenCut shell — 3-column NLE + floating Composer window
Reshape the editor frame to OpenCut's layout (Assets | Preview | Properties
over a full-width Timeline), keeping every panel's mount point so existing
modules keep working:

- index.html: single horizontal main-row of three resizable columns; preview
  is the flexible center, Assets/Properties flank it. Plan strip removed
  (recipe now lives in the Properties column per the one-timeline model).
- styles.css: new workspace layout + graceful column-toggle degradation;
  floating-window + Composer-button styling.
- app.js / layout.js: rewire splitters (--media-w / --properties-w / --timeline-h)
  and column-visibility chips for the new arrangement.
- floating_window.js: reusable OS-style window (drag / minimize-to-pill /
  maximize / close); foundation Models & Engine settings can adopt later.
- composer.js: Composer window hosting Characters / Shortcuts / Split markers,
  toggled by a header "Composer" button.
- remove plan_strip.js (superseded).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:18:47 +03:00
digital-garbageandClaude Opus 4.8 a303052941 opencut_ui: credit OpenCut in README Thank You section
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:53:39 +03:00
digital-garbageandClaude Opus 4.8 ea20c018f8 Movie Editor: removing a scene from the plan keeps its generated clip on the timeline
'Remove from plan' (plan card) now: if the gen-unit has a render, mark it excluded
(so generation + prompt skip it everywhere — reuses every existing !excluded filter,
no audit) plus removed_from_plan (hide from the plan strip, override the single export
skip so the clip still renders, and skip the 'excluded' dim styling). Ungenerated
scenes are still a plain delete. Inspector shows a 'Restore to plan' banner on an
off-plan scene; timeline marks it with a subtle dashed outline.

This retires ghosts for the plan-removal path: the removed scene persists as a real
result clip in the cut, not a separate ghost. New Scene.removed_from_plan field
(persisted). Backend tests green (62).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 10:22:26 +03:00
digital-garbageandClaude Opus 4.8 07eaec5690 Movie Editor: timeline cut order independent of plan order
The timeline is the result; its order is now project.timeline_order (scene ids),
which plan reorder never touches. buildPreviewSegments + _renderClips (export) read
this cut order via orderedTimelineScenes(); it's self-healing (drop gone ids, append
new scenes in plan order) and maintained on load + structure change, with a backend
field so it persists.

- Menubar 'Move Clip Left/Right' reorders the CUT (moveTimelineClip → timeline_order).
- Plan-card '← Plan / Plan →' reorders the PLAN (moveScene → scenes / generation order)
  without moving the timeline clip.
- view_bus fingerprints include timeline_order so a cut reorder re-renders.

Reordering the plan no longer moves or alters already-generated videos on the
timeline. Backend tests green (62). Empty timeline_order falls back to plan order
(back-compat). Still TODO: 'remove from plan keeps the clip on the timeline'
(ghost retirement) — entangled with generation/export skip semantics, do next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 10:16:28 +03:00
digital-garbageandClaude Opus 4.8 93c8068b90 Movie Editor: i2v anchors drop on the Plan, not the timeline
The timeline is the rendered result, so setting up a generation must not touch it.
Removed the clip-level anchor drop and the timeline track's image->anchored-scene
drop. Image media now drops onto Plan cards (sets that scene's i2v anchor) or onto
empty Plan space (creates a new anchored scene). Video clips (finished results)
still drop on the timeline track. Plan-only image filter; teal drop-target hint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 10:01:21 +03:00
digital-garbageandClaude Opus 4.8 4f562cf0ff Movie Editor: timeline clip shows what it was generated with, not live plan text
Completes untying plan edits from the rendered result on the timeline. The clip
is the RESULT, so it now labels itself from the frozen render prompt
(renderPromptForScene) instead of the live scene text — editing a scene's prompt
in the plan no longer mutates the already-generated clip's identity here (it just
shows 'edited' until you regenerate). Falls back to live plan text only when the
scene isn't generated yet. Video clips unchanged.

With the earlier immutable-length fix, a plan edit (prompt/length) now leaves an
existing generated video's content, duration, AND label on the timeline alone;
only regeneration updates it. Editorial props (effects/trim/audio) stay live.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 09:53:41 +03:00
digital-garbageandClaude Opus 4.8 af07b7bb25 Movie Editor: add Plan strip (scene recipes above the result timeline)
New plan_strip.js band (#plan-zone) above the timeline: compact recipe cards
(anchor thumb + prompt + status: not generated / in sync / edited), click to
select, chevron opens a full-width inline editor (prompt, source, anchor picker,
Generate this scene, Remove, Advanced -> inspector). Collapsible. Placed above
#split-bottom so the timeline splitter / --timeline-h math is untouched; it's a
bounded, additive band (dock flex:1 absorbs it).

Plan = 'what will generate'; the timeline below is the immutable rendered result.
Edits are quiet/debounced and the band won't rebuild while a field is focused
(no input disruption). Selection syncs with the timeline.

Phase 1 / additive: the inspector's per-scene panel is intentionally kept as the
full editor + fallback (the plan can be Hidden) — retiring/merging it and removing
ghosts are the next steps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 14:00:46 +03:00
digital-garbageandClaude Opus 4.8 4fb7e66759 Movie Editor: remove 'Convert to video/scene' buttons from the UI
The convert verbs don't fit the revamped plan/result direction and need a
rethink (see deferred notes). Remove the toolbar buttons now and the two
inspector hints that pointed at them, so nothing references a control that's
gone. The convertToVideo/convertToScene store functions are left intact and
callable — only the UI entry points are removed; the rework comes later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 13:48:51 +03:00
digital-garbageandClaude Opus 4.8 0c7fe14b79 Movie Editor: generated renders are immutable, full-length (no truncation by plan changes)
A render never recorded the length it was actually made at — sceneDurationSec
recomputed from the LIVE plan every time, so changing project/scene length
retroactively truncated already-generated videos and made their tail unreachable
in the preview, player, and final export alike.

Now each render freezes its real length at generation time (durationSec). A
generated scene in project (default) frames mode plays/lays-out/exports at that
frozen length; the project/scene default only drives the NEXT generation.
Explicit per-scene length (timeline/custom), slip-trim, and splits still win
(a split clears the frozen length so both halves revert to plan layout).

- store: renderDurationSec + _planDurationSec; sceneDurationSec is render-aware;
  _recordSegment freezes durationSec on scene renders and ghosts; trim/resize
  measure from the shown length; segmentDurationSec delegates ghost length to
  _ghostDurationSec (de-dupes the inline calc).
- inspector: scene duration hint shows 'Rendered ~Xs - plan Ys - Regenerate to
  apply' when a render is frozen at an older plan length.

Centralized in sceneDurationSec so timeline, player, audio offsets/durations and
the final stitch all agree. No-op in the common case (plan == render). Renders
made BEFORE this change have no frozen length and stay plan-driven until
regenerated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 13:33:57 +03:00
digital-garbageandClaude Opus 4.8 6d25c8c1c5 Movie Editor: real min/max/step on exposed controls + stop autosave from eating input
Exposed node controls (e.g. a LoRA strength in project settings) now carry the
node's actual min/max/step/default from object_info instead of step=1/no bounds:
- capture numeric widget meta at expose time and on link creation (models.js)
- apply it in the Models node editor and the inspector's Exposed controls
- backfill meta onto pre-existing exposures when Models is opened / refreshed

Typing an exposed value no longer gets disrupted: the field now carries a data-k
so the edit guard protects it, and setModelInput/setModelLink update in place +
debounce the server save (was one saveModels POST per keystroke, notifying twice
and rebuilding the field mid-type). Pending model saves flush on blur and before
generate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 12:38:22 +03:00
digital-garbageandClaude Opus 4.8 94ffbb3cda Movie Editor: fix inspector input/label/control UX papercuts
- Rebuild guard now protects only typed/dragged fields (text/number/range),
  not selects/checkboxes — so dependent controls (custom length input, Ken
  Burns knobs, Steer mode 'absolute', Embed/Mid-scene guide) reveal on the
  toggle instead of only after blur (inspector.js + engine_settings.js).
- Tag blend-length and video 'Source in' fields so non-quiet patchScene no
  longer yanks them mid-type.
- Blur % and Zoom amount % slider labels update live while dragging.
- Surface Width/Height in the Project Output section (out of the collapsed
  Advanced fold); leave Max scenes in Advanced.
- Custom scene length reflects its snapped value back into the field on commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 12:28:31 +03:00
digital-garbageandClaude Sonnet 4.6 0d909f4b18 Fix: single-transition 'silent' split leaked the trigger word into conditioning
With exactly one transition trigger in the prompt (one "cut", one "qcut", etc.),
split_scenes produced anchor + 1 scene — so len(canon_scenes) == 1. The
previous guard `> 1` skipped the clean-text encode path, leaving
output_conditioning built from the raw prompt_to_encode which still contained
the trigger word. The CLIP encoder received "cut" and the model generated it
in audio.

Changing to `>= 1` ensures any split with at least one clean scene uses the
properly stripped scene text, even when there's only one scene to encode.
The chain sampler receiving a single conditioning entry is fine — it just
renders a single pass with no chaining.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 20:18:21 +03:00
digital-garbageandClaude Sonnet 4.6 ec61f169fe Remove FunPackNormalizingSampler (redundant)
Normalization is now available in both Hybrid Euler 2S and Distilled Flow
samplers, making the standalone Normalizing sampler redundant. Removes the
node class, its sampler function, two private helpers (_parse_norm_factors,
_apply_av_norm_factors), the Studio/Movie Editor "Normalizing" type option,
and the defaultNormalizing() factory. Stale "same as the Normalizing sampler"
tooltip references in both sampler nodes are updated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 19:05:11 +03:00
digital-garbage cb25c14e8d Movie Editor: coerce stale LoRA/combo slot values to live choices
A renamed or removed file (e.g. an old distilled LoRA) left a slot's saved
combo value out of sync with object_info's current choices. The Models menu
select then showed the live first choice (browser default for "no matching
option") while the saved config still held the stale string, which the
builder passed straight through to ComfyUI and failed validation.

Coerce in both places: the builder falls back unknown combo values to the
node's current default/first choice, and the Models menu select persists
what it actually displays instead of leaving the stale value on disk.
2026-06-16 00:23:31 +03:00
digital-garbage cddb928608 Merge branch 'cutting_edge' into dev 2026-06-16 00:15:52 +03:00
digital-garbage 0bf8cbc6b9 Movie Editor: fix timeline not re-rendering after prompt edits
onStore marked the data fingerprint as handled before checking whether
render() actually redrew. render() can decline (focus/drag/scroll), so
post-generation prompt edits left the timeline showing stale text and
the "Generated with" badge. Only commit the fingerprint when the render
succeeds, both in timeline.js's onStore and view_bus.js's subscribeZone.
2026-06-16 00:13:42 +03:00
digital-garbageandClaude Opus 4.8 c2c9be6ce8 Remove the Scene Builder (Studio/Refiner) entirely
Deletes the FunPack Scene Builder node and the Studio Scene Builder feature
— the per-key scene database (scene_db / universal_memory / saved scenes),
the Studio "Scene" tab, scene-phrase authority over classification, and the
scene-database wildcard cleanup. It was redundant: helpful on paper but
effectively unused, undrivable from the Cutting Room, and a risk to shortcuts.

Removed:
- node registration (__init__.py, funpack.py) + web/funpack_scene_builder.js
- templates.py: scene-DB storage layer (load/save/normalize/empty_scene_db,
  SCENE_DB_VERSION/SCENE_STATE_FIELD/SCENE_CATEGORY_SOURCES, scene_store_path),
  all scene_* helpers, resolve_scene_database_wildcards, the FunPackSceneBuilder
  class, and the /funpack/scenes* routes
- conditioning.py: _v2_scene_builder_db / _v2_scene_memory_item /
  _v2_apply_scene_builder_authority / _v2_scene_builder_category_for_entry /
  _v2_sync_scene_builder_memory / _v2_resolve_scene_builder_wildcards (+ wildcard
  helpers + _v2_scene_key), the scene_db threading through classify/learning,
  the scene_category_locked phrase fields + their training branch, the
  state["scene_builder"] preservation, and the Studio scene_builder prompt mode
- web/funpack_studio.js: Scene tab, SB_MODES, scene_builder settings, renderScene,
  fetch/saveScene, the Session Scene-Builder section, and the Refiner banner/notice
- tests/test_scene_builder.py (whole file) + scene-builder tests in
  test_v2_category_alignment.py; the SceneBuilder example workflow + its doc;
  README link; Scene Builder mentions in docs/FunPackStudio.md

Kept intact: shortcuts (apply_prompt_shortcuts / shortcut DB), transitions and
the canonical split_scenes splitter, and FunPackRefinementKeyLoader. Studio now
always uses the connected positive_prompt. No new test failures (the 16/97
remaining in tests/ are pre-existing env/sampler failures); movie_editor 140 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:31:31 +03:00
digital-garbageandClaude Opus 4.8 648a7401c6 Movie Editor: don't prune a just-finished ghost on generation end
A scene removed mid-generation becomes a ghost; when that in-flight run
completes, _recordSegment attaches the finished media to the ghost
(pendingGen:false) and deliberately does NOT push its id to
recordedSceneIds. But _pruneGhostsAfterRegen dropped any ghost whose
afterSceneId was in recordedSceneIds — and a ghost anchored after a sibling
scene in the same run matches that, so the freshly-finished ghost was
removed from the timeline the instant generation ended.

Collect the ids of ghosts that received media this pass (completedGhostIds)
and protect them in _pruneGhostsAfterRegen. Genuinely stale ghosts (anchored
after a recorded scene, not updated this run) still get pruned as before.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:49:00 +03:00
digital-garbageandClaude Opus 4.8 df011b927f Stage 2 Part B: "Wrong appearance" → consistency anchor
Reworks the "Wrong appearance" rating from a (now-removed) prompt-repair
signal into a conditioning-level consistency anchor (option b). "Wrong
appearance" now means "character consistency wasn't preserved" and steers
the next generation back toward the established character.

Capture (_v2_update_appearance_anchor, wired into both the single-run
learning path and the shared per-scene suite _v2_learn_scene_into_state):
  - good rating (like/nailed_it/loved_it/loved) → store the rated run's
    conditioning as the per-key "blessed appearance" (overwrite = last good)
  - wrong_appearance → store the rejected run's conditioning as the "drift"
global_state is already per-refinement-key, so both live with that key.

Apply (_v2_apply_conditioning_memory_impl, after the intent-family delta):
when the user rated the previous gen wrong_appearance, gently pull this gen
toward the blessed appearance (lerp 0.05) and repel from the drift (0.04),
reusing _v2_apply_conditioning_payload / _v2_repel_conditioning_payload. No
ramping; the existing 7.5% delta cap bounds the net effect. No-op when
nothing is stored or shapes mismatch.

Drops the dead wrong_categories field (zero consumers after Part A) and
keeps skip_value_function (the anchor is a conditioning nudge, not a reward).

Tests: 7 new unit tests (storage + overwrite + skip + pull/repel + idle +
non-trigger); updated test_wrong_appearance_rating_is_available for the new
semantics. Zero new failures vs HEAD (the 10/31 remaining are pre-existing
env failures from missing server/comfy modules).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:44:55 +03:00
digital-garbageandClaude Opus 4.8 2fec7280ab README: document cutting_edge branch under Dev and Cutting Edge branches
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:27:47 +03:00
digital-garbageandClaude Opus 4.8 52fbb5b461 README: document cutting_edge branch under Dev and Cutting Edge branches
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:27:35 +03:00
digital-garbageandClaude Opus 4.8 61e7097416 README: document cutting_edge branch under Dev and Cutting Edge branches
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:27:15 +03:00
digital-garbageandClaude Opus 4.8 e39a64de57 Stage 2 (2/3): delete dead prompt-repair methods + their tests
Removes the now-unreferenced repair-only machinery left behind after
Stage 2 (1/3) neutralized the application:
  - _v2_prompt_repair_text_allowed
  - _v2_emphasized_prompt
  - _v2_repair_prompt_for_missing_axes and the repair-candidate helpers
  - perfect_repairs / rejected_repairs storage + perfect-repair eviction
    note in the intent-family learn path
Shared helpers still used by intent-alignment (e.g. _v2_repair_intent_roots,
_v2_repair_candidate_matches_intent, _v2_prompt_contains_text) are kept, as
is the repair_feedback / active_repair_axes "what's missing" signal the
advisor reads.

Deletes the 11 category-alignment tests that exercised the removed methods
directly. No new test failures (the 10/31 remaining are pre-existing env
failures from missing server/comfy modules).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:25:44 +03:00
digital-garbageandClaude Opus 4.8 65816e353a Stage 2 (1/3): remove the prompt-repair application + param
Neutralize the repair application in refine(): the intent-aligned prompt is
encoded as-is — perfect-repair phrase injection, missing-axis repair, and the
emphasis pass are gone. The advisor remains the only prompt-rewriting path, and
repair_feedback/active_repair_axes is KEPT (it's the 'what's missing' signal the
advisor still reads). Drop the prompt_repair param from refine(), INPUT_TYPES,
FunPackStudio, and both UIs (web + engine_settings).

The dead repair-only methods (_v2_repair_prompt_for_missing_axes, perfect-repair
phrases, etc.) come out in the next commit; shared helpers like
_v2_repair_intent_roots (used by intent alignment) stay.

Deleted the now-obsolete test_repair_candidates_saved_as_json_lists (tested the
removed injection). No new test failures vs dev.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:15:28 +03:00
digital-garbageandClaude Opus 4.8 91affc5359 Stage 1 cleanup: delete dead splitter method; preview uses split_scenes
Generation now reads split_scenes, so the duplicate _v2_split_prompt_by_transitions
method has zero callers — deleted. bridge.parse_timeline (the 'what Studio sees'
preview) now derives from split_scenes too, so the preview's scene count/boundaries
match generation exactly (no spurious 'split produced N but timeline has M' warnings).

The lossless RAW editing split (parse_timeline_verbatim / split_timeline_verbatim)
stays separate — it has a genuinely different lossless requirement (round-trips the
exact typed text). It still uses the old offset-projection path; converting it to a
lossless piece-walker is the one remaining Stage-1 loose end.

Tests: 33 + 140 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 13:20:28 +03:00
digital-garbage 9df7c654ac Reapply "Stage 1: generation reads split_scenes too — guard removed"
This reverts commit 1b98baaa3fbcfd4e4cd6f834401b30e36afe1e1e.
2026-06-15 13:16:46 +03:00