Skip to content

Release v0.29.0: aligner word timings, reviewed batch plans, render fidelity and lint checks - #142

Merged
renezander030 merged 6 commits into
masterfrom
release/0.29.0
Oct 9, 2026
Merged

renezander030 merged 6 commits into
masterfrom
release/0.29.0

Conversation

@renezander030

@renezander030 renezander030 commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Release v0.29.0: nine additions, ordered by expected user value. Version bump, CHANGELOG, README highlights (EN + zh-CN) and the regenerated command reference are included. Nothing is tagged or published.

What's in it, in priority order

  1. render fidelity census + render --strict: every render result and --dry-run plan reports what the proxy leaves out compared with the app (transitions, effects, filters, masks, keyframes, uncomposited overlay tracks, stickers, animations, blend modes, chroma key, matting, missing media, closed gaps), with counts, segment ids and faithful. --strict refuses (refused [render-unfaithful]) before anything is written. Why first: pipelines that preview drafts with render had no machine-readable way to tell how far the preview was from what the editor will show.
  2. Reviewed batch plans: batch --plan <plan.json> / batch --apply-plan <plan.json>: the plan holds the normalized operations, a dry-run preview per operation, draft_sha256 and operations_sha256. Apply refuses when the draft changed since review (plan-draft-changed), when the operations were edited (plan-tampered), or when the plan names another project (plan-project-mismatch). Why: an agent's edits can now be reviewed as an artifact and applied exactly as reviewed.
  3. render output verification + render --verify: after a real render, ffprobe measures the file and verification reports duration, expected duration, drift and a one-frame tolerance. --verify exits non-zero on drift or an unverifiable file. Why: catches encoder padding and speed-rounding drift between the preview and the timeline.
  4. caption --words <file.json|->: captions from word timings produced by any external aligner, with no Whisper needed. Formats detected: Whisper / whisper.cpp, WhisperX, and plain word or character lists in s/ms. Grouping, CJK joining, --script, --karaoke and --word-reveal work as before. refused [words-invalid] names a bad entry. Why: users who already have accurate, corrected timings (often per character for Chinese) could not bring them in.
  5. Whisper-free caption routes documented: docs/quickstart.zh-CN.md (不装 Whisper 的字幕路线) and examples/short-video-narration.md cover three routes: app auto-captions then restyle / export-srt, import-srt, and caption --words. doctor's Whisper hint names them. Why: installing Whisper is the biggest setup hurdle for Chinese users.
  6. tts --lexicon <file.json>: pronunciation rules rewrite only the text sent to the TTS engine. Longest match wins, matching respects word boundaries, and CJK rules match anywhere. Ambiguous or malformed lexicons refuse before the engine runs, and the result reports every substitution. Why: fixing a mispronounced name no longer means misspelling the script.
  7. lint segment-overlap (error) on non-text tracks, and --fix for overlaps of up to one frame (the independent-rounding overlap). Wider overlaps are reported only. Why: overlapping video/audio segments passed lint clean, although the editor never allows them.
  8. Write journal: every undo snapshot records command, argv, time and before/after sha256. restore --list shows which command produced each step. A torn journal never blocks a write or a restore. Why: rolling back an agent's change no longer means guessing the step number.
  9. lint segment-offscreen (warning): flags segments that cannot be seen, either because their box lies entirely outside the canvas (rotation allowed for) or because scale or opacity is 0. Keyframed properties are not judged. Why: an off-canvas transform shows up only as a black preview.

Verification

  • Full suite on the release branch: 1211 tests, 1210 pass, 0 fail, 1 skipped (node --test test/). Base v0.28.0: 1134 pass, 1 skipped. That is 76 new tests across render-fidelity, batch-plan, write-journal, caption-words (with fixtures for each word format), tts-lexicon and lint-overlap-offscreen.
  • The pre-commit gate (npm test, a fresh build) passed on the release commit: 1217 pass, 0 fail, 1 skipped.
  • biome check --error-on-warnings src/ test/: clean.
  • npm run smoke:package against a freshly packed tarball: PASS. It covers a fresh install, CLI/library/version, compile, media registration, queue, redaction and active-timeline writes.
  • Manual run on a freshly inited draft: caption --words with per-character Chinese timings produced the joined cue 你好 (words_format: word-list), restore --list attributed the step to caption with its argv, and lint came back clean.

Review notes

  • Base: cb348ed (v0.28.0). One commit per feature area, plus a release commit. No other open PRs overlap.
  • Touched: src/render.ts, src/lint.ts, src/caption.ts, src/draft.ts (history journal), src/doctor.ts (hint text only), new src/lexicon.ts, src/index.ts, src/command-specs.ts, docs and tests. Store discovery, active-timeline selection, write guards, compile and the Python client are unchanged.
  • Behaviour change to check: lint --frame-grid --fix now shares the overlap repair's duration helper. At speed 1 nothing changes. On clips at other speeds whose source duration matched target × speed (within 1%), the source duration now follows the snapped target instead of staying put.
  • Result-shape choices: render verification lives in a new verification field, because output already holds the path. --plan takes a value only for batch and stays a boolean for compile. --words places cues from timeline 0, like --audio.
  • segment-offscreen treats text, stickers and media of unknown size as canvas-filling at scale 1. It can miss some off-canvas cases but raises no false alarms. visible is not judged.

segment-overlap (error) reports overlapping segments on every non-text
track; --fix ends the earlier segment at the next start for overlaps of at
most one frame, keeping source duration proportional to speed. Wider
overlaps stay report-only. segment-offscreen (warning) reports visual
segments that are off the canvas, at zero scale or at zero opacity, skipping
a reason whose property is keyframed.
Every render plan (dry-run included) now carries a fidelity object listing
what the proxy leaves out for the draft at hand, per category with counts and
segment ids, plus faithful and expected_duration_us. --strict refuses with
refused [render-unfaithful] before anything is written. A real render probes
the written file with ffprobe and reports verification (duration, drift,
one-frame tolerance); --verify exits non-zero on drift or when the file
cannot be probed, keeping the file.
Rules rewrite only the text handed to the TTS engine: leftmost-longest
matching at word boundaries (CJK rules match anywhere), optional
case-insensitive rules, and refusals for malformed (lexicon-invalid) or
ambiguous equal-length rules (lexicon-ambiguous) before any engine runs.
The result reports the applied rules with UTF-16 offsets and the spoken text.
…thout Whisper

Accepts Whisper/whisper.cpp segments[].words[], WhisperX word_segments[]
and plain {word|text|char,start,end} arrays (seconds, *_ms, *_time keys),
reports words_format and words_skipped, refuses out-of-order or end<start
entries. Documents the Whisper-free caption routes (zh quickstart, English
narration example) and adds them to doctor's whisper hint.
batch --plan <file> validates stdin operations in memory as a real run
would and writes a plan with the draft and operations sha256 plus a
per-operation preview, leaving the draft untouched. batch --apply-plan
<file> re-hashes both and refuses with [plan-draft-changed] or
[plan-tampered] before applying through the transactional batch path.

Every history snapshot now appends a line to
<draftbase>.journal.jsonl naming the command, argv, time and
before/after sha256; trimming keeps it aligned with the snapshots and
restore --list shows command, argv and time per step. Unreadable
journal lines are skipped.
…idelity and lint checks

Version bump, CHANGELOG 0.29.0 section, README release highlights (EN + zh-CN)
and regenerated command reference.
@renezander030
renezander030 merged commit 648f469 into master Oct 9, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant