drawClipWaveform picked a nearest source-peak sample per pixel column. That
works when zoomed out (many samples per pixel, downsampled via max so
transients survive), but zoomed in past the peaks array's native
resolution, multiple adjacent pixel columns landed on the same sample and
repeated its flat value, stepping abruptly to the next - the square
staircase look reported. Now interpolates linearly between the two
neighboring samples whenever a pixel covers less than one sample, restoring
the smooth capsule-shaped envelope; the max-downsample path is unchanged
for the zoomed-out case. Verified at max horizontal zoom in the live editor
- Compare (Wipe) is nothing to do with this file - screenshot before/after
confirms the blocky steps are replaced by a continuous curve.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- export.py: image inputs in a transition were capped at 1 frame of loop
duration (dur_sec=0), starving the trim below - use the actual duration
each side's trim needs instead. Verified with a green-image -> blue-video
fade export: pixel values step smoothly (0,126,0) -> (0,62,127) ->
(0,10,231) across the 12-frame window, matching a linear crossfade.
- app.js existingTransitionPair(): stopped reordering [a,b] by start time,
which discarded which clip actually carries transition_type - could make
Remove Transition clear the untagged clip and leave the real tag dangling.
- app.js addTransitionSelected(): reuse an existing group_id instead of
always minting a new one, so linking A+B doesn't silently detach either
from an unrelated pre-existing group; refuse to link if they already
belong to two different groups.
- app.js removeTransitionSelected(): only clear a clip's group_id if no
other clip still shares it (preserves a larger group B was merged into);
search other lanes to restore B's position if its original spot is
occupied, and say so in the status message instead of claiming success
when it couldn't move B back.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Replace native confirm()/alert() with the app's own modal for media and
project deletion - a browser-owned dialog can be silently suppressed
inside a cross-origin/sandboxed iframe (e.g. the ComfyUI preview node),
which read as "delete does nothing"
- Add librosa to standalone dependencies (pyproject.toml, install/update
scripts) - AI Detect's beat tracking needs it and standalone was missing
it entirely (ComfyUI's own env already had it, masking the gap)
- Revert Auto Stitch to plain hard-cut only, no transition options
- Add a separate Transition feature: select 2 adjacent clips, choose a
type/duration, and it overlaps them (moving B to a free lane) with a
shared group_id so dragging one drags both - keeping the overlap intact
instead of silently breaking on an independent move. The same button
becomes "Remove Transition" for an existing linked pair, unwinding back
to a plain adjacent cut.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Excluding update_standalone.ps1/Update_ITDA_Standalone.bat from the files
an update replaces - cmd.exe reads a .bat line-by-line as it executes, so
overwriting the very file it's mid-way through running (as the previous
version did, via git pull/copy including these two) corrupted its read
position and threw a garbage command error right after the real update work
finished.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Auto Stitch: optional crossfade/interpolate transition bridge between clips
(itda/stitch.py render_bridge, itda/server.py stitch_bridge endpoint)
- Timeline: real xfade-based transitions (dissolve/wipe/slide/etc.) between
overlapping clips on export (itda/export.py)
- Standalone app: itda_standalone.py entrypoint, routes/paths made
ComfyUI-optional (itda/server.py, itda/paths.py), install/update scripts
- Send To ComfyUI: HTTP upload path for standalone mode with no shared
filesystem (itda/media.py send_clip_to_comfy_http, via ComfyUI's own
/upload/image API)
- Fix box-select cursor misalignment (duplicate ruler-height offset in the
visual box, double-counted scroll in the lane hit-test)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Registry review requires English-only tooltips, and every app-authored
string may as well match. The remaining Korean in the editor is the user's
own data (media filenames, text clip contents), which must render as-is.
- Translate the four remaining Korean strings (save confirmation, empty
media bin, media delete confirm, project library and settings notes) and
set <html lang="en">.
- Give both nodes a DESCRIPTION, per-input tooltips and OUTPUT_TOOLTIPS;
there were none before, so the graph gave no hint how they connect.
- Add pyproject.toml with the [tool.comfy] metadata the registry expects.
- Ignore .claude/ and drop the local v1.0 cleanup backup.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Completes the v0.1.5 -> v1.0 roadmap and hardens the path handling around it.
Features
- Auto Stitch: recommends where to cut between two clips, scoring candidates
on frame similarity and optical-flow motion continuity (recommend + Apply,
never an automatic edit).
- AI Detect: scene-change detection (ffmpeg scene score) and beat tracking
(librosa), with beats used as snap targets.
- Pre-render: flattens the marked range into one cached file for smooth
playback; invalidated automatically by any edit.
- Version Stack, Wipe Compare, Box/Shift select, per-clip Solo/Gain,
MOV/WebM export, whole-timeline Send To ComfyUI.
Security
- Contain clip paths on export. A clip's path is read from the project file
and POST /itda/api/project/<name> stores arbitrary JSON, so any local
process could point a clip at any file, have ffmpeg composite it into the
export, and fetch it back via /itda/api/file.
- Contain the export path in ITDA Load Export. The node trusted "path" from
last_export.json and handed it straight to a decoder, so a tampered
manifest could emit any file's contents as node output.
- Reject dot-only project names. safe_name() stripped separators but passed
"." and ".." through, collapsing media/<project> to the whole ITDA root;
media/delete would then accept any file under input/ITDA.
- Validate drawtext colors. Unvalidated color/shadow_color were interpolated
into the ffmpeg filter, so "ffffff:textfile=..." appended a real drawtext
option. Also set expansion=none.
Fixes
- ffmpeg no longer blocks ComfyUI's event loop (an export froze the whole UI
for its duration); all calls now run off-loop.
- Auto Stitch no longer ranks on audio: measured against known-correct cut
points it could not separate good cuts from bad, and demoted the perfect
cut to last. Frame + motion scores 5/5 on ground truth.
Removed itda_server.py, web/itda_editor.html/.css and an empty
itda_client.js (all superseded and unreferenced), and stopped tracking
__pycache__.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>