Files
malkuthro-ComfyUI-Koolook/forks
malkuthroandClaude Fable 5 3608ab5a21 fix(ltx): scrub base64 posters from persisted Director timelines (draft-quota toast storms) (#277)
* fix(ltx): scrub base64 posters from persisted Director timelines

The vendored upstream 2.0.2 timeline editor stamps a base64 poster JPEG
onto every video segment (canvas.toDataURL) and kept it across serialize
round-trips, so timeline_data - and with it the workflow draft ComfyUI
1.44+ writes to localStorage ~512ms after every edit - grew by ~50-150k
chars per video segment. Large timelines then exceeded the origin quota
no matter how many old drafts koolook_draft_guard.js evicted, and the
frontend latched its session-wide storage-unavailable flag: every edit
toasted "Failed to save workflow draft" until reload.

Reinstate a minimal media scrub as a third documented Koolook delta,
applied at all six persist/restore maps (commitChanges + parseInitial):

- video / motion_video posters with a backing file (imageFile on the
  main track, videoFile on the motion track) are dropped; the seeked
  handler re-derives them from the video element on load
- legacy pre-2.0.2 image segments carrying full inline data-URLs are
  rewritten to the /view URL form 2.0.2 itself writes (loadMedia renders
  image previews from imageB64 only - deleting would blank them)
- legacy inline audioB64 (raw base64) is dropped when audioFile exists;
  playback only falls back to it when no file resolves
- blobs with no backing file are left untouched

Disk Save / Save As payloads stay unscrubbed on purpose: exported .json
keeps upstream's format and meets the restore scrub on load. On-screen
previews are unaffected - only persisted copies are scrubbed.

Covered by Node behavior tests that evaluate the delta block against a
stubbed api, plus a source contract that all six maps route through the
scrub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ltx): persist the scrubbed timeline on restore; review follow-ups

Addresses the verified findings on #277.

The restore-time scrub only updated the editor's in-memory timeline. The
node's timeline_data widget kept the original payload, and that is what
onSerialize and LiteGraph's widgets_values read - so an already-fat saved
workflow still fed the draft autosave that fires on load, before any edit
triggers commitChanges. Both restore paths (the onConfigure sync block and
the editor constructor) now rewrite the widget from the scrubbed timeline.
The round-trip is lossless: parseInitial whitelists exactly the keys
commitChanges persists. Chose this over calling commitChanges during
configure, which would also recompute the prompt/length/strength widgets on
every node's configure - far wider blast radius than the defect warrants.

Also:
- keep the data-URL when a malformed imageFile yields no /view URL, instead
  of blanking the preview with an empty string
- rewrite the stale provenance-header paragraph that still claimed the
  base64-scrub deltas were obsolete (it now contradicted the third delta)
- update the v2.0.2 entry in forks/forks_manifest.yaml from "two retargeting
  edits" to the three current Koolook edits, with the scrub's rationale
- note the audioB64 leg and the widget rewrite in the CHANGELOG entry

The bare catch in parseInitial is left alone: pre-existing upstream
behavior, and the scrub introduces no realistic new throw.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ltx): trigger the widget rewrite on legacy raw-base64 audio too

The restore-time widget rewrite gated on the payload containing "data:",
which catches the poster/image blobs that caused the quota storms but not
the scrub's third removal: legacy audioB64, which is raw base64 with no
"data:" prefix. An audio-only fat timeline would have its memory scrubbed
while the widget stayed fat until the next commitChanges.

Gate on either token instead, so the trigger covers everything the scrub
actually removes. A false positive still costs only a lossless rewrite.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-10 11:16:37 +02:00
..

Forks Workflow

This folder is the single source for all fork tracking metadata inside MAIN.

Purpose

  • Keep modified forked code in MAIN under versioned paths (for GitHub tracking).
  • Keep raw external checkouts outside MAIN under ../ComfyUI-Forks (for upstream reference/sync).
  • Keep all fork metadata in one place:
    • forks/forks_manifest.yaml
    • forks/THIRD_PARTY.md

Folder Layout in MAIN

  • forks/radiance_koolook/__init__.py -> package entrypoint used by root __init__.py
  • forks/radiance_koolook/versions/v2_3_3/ -> local modified node sources (currently the only active version)
  • forks/radiance_koolook/versions/<version>/UPSTREAM_PIN.yaml -> exact upstream parity pin

The earlier v1_0_1 fork was removed in v0.1.5 — see THIRD_PARTY.md for the rationale and recovery instructions.

External Folder Naming (outside MAIN)

Root: ../ComfyUI-Forks

  • Pinned baseline checkout:
    • radiance-v2.3.3-koolook
  • Rolling upstream checkout:
    • radiance-main-upstream

These names are referenced from forks/forks_manifest.yaml.

Referencing System

For each fork entry in forks/forks_manifest.yaml:

  • source_repo = canonical upstream URL
  • source_ref = release/tag (or baseline descriptor)
  • pinned_commit = exact reproducible commit hash
  • external_checkout.relative_path_from_forks_root = pinned raw reference folder
  • external_checkout.upstream_tracking_path_from_forks_root = rolling upstream folder
  • local_paths = files tracked in MAIN

Tagging Policy (from now on)

  • MAIN repo tags use SemVer: vMAJOR.MINOR.PATCH.
  • Local fork version folders use underscore variant of the same version:
    • v2_3_3, v2_4_0, etc.
  • Node mapping namespace suffixes must match folder versions:
    • __koolook_v2_3_3, __koolook_v2_4_0, etc.
  • Some node IDs opt out of the suffix via SKIP_VERSION_SUFFIX (see forks/radiance_koolook/versions/v2_3_3/__init__.py) to keep stable user-facing IDs across upgrades.
  • Keep source_ref + pinned_commit in forks/forks_manifest.yaml and UPSTREAM_PIN.yaml.

Upgrade Flow Example (Radiance)

Hypothetical bump from the current v2_3_3 to a future v2_4_0:

  1. Compare current local version (forks/radiance_koolook/versions/v2_3_3) with pinned raw baseline (../ComfyUI-Forks/radiance-v2.3.3-koolook).
  2. Pull latest upstream in ../ComfyUI-Forks/radiance-main-upstream.
  3. Create a new local version folder in MAIN, e.g. forks/radiance_koolook/versions/v2_4_0.
  4. Port/validate modifications.
  5. Namespace node IDs for that version (or keep them stable via SKIP_VERSION_SUFFIX when upstream IDs are unchanged).
  6. Add new entry/update metadata in forks/forks_manifest.yaml.

For the underlying mental model — three independent version axes (pack version / fork wrapper version / upstream pinned commit) — see docs/reference/versioning.md.

Rule of Thumb

  • If it is modified production code -> keep in MAIN under forks/.../versions/...
  • If it is raw upstream reference -> keep outside MAIN under ../ComfyUI-Forks