v1.16.0
1.16.0 — caption position goes native (import-captions --transform-y)
Minor release. import-captions learns where to put the captions: the new
--transform-y <n> flag sets clip.transform.y on every rebuilt caption segment,
which used to be hardcoded to the screen centre ({x:0, y:0}). Output is
byte-identical whenever the flag is not used.
The problem it solves
import-captions REPLACES the text track and rebuilds each segment at transform
{0,0} — centre screen. Pipelines that want captions lower (TikTok mi-bas /
lower-third) had to re-pin transform.y AFTER the import with an orchestrator-side
patch step (Niche_PC's step 3b restore_caption_transform), or order the chain so
a final restyle re-grafts the position from a gabarit. With the position native
to the import, the re-pin step disappears and import-first chains keep their
position without a trailing restyle.
Highlights
- 📍
import-captions --transform-y <n>— every rebuilt caption segment gets
clip.transform.y = n. Global flag only (no per-card field).transform.xis
never touched. - ➖ Negatives and zero allowed. The value is validated as a finite number
(newparseFiniteFlag) — unlike the strictly-positive size flags.-0.4=
mi-bas,-0.6= lower third,0= centre. - 🧬 Clone-style aware. The segment build is shared, so the flag works
identically with and without--clone-style. - 🛡️ Validation. Non-numeric (
abc), empty ("") and whitespace-only values die
with a clear CliError — theNumber("") === 0JavaScript coercion trap is guarded
explicitly. The two malformed spellings that would otherwise degrade to ignored
positionals are refused as well:--transform-y=-0.4(equals syntax) and a
value-less trailing--transform-yboth die instead of silently importing your
captions recentered at y=0 with exit 0. - 🚩 Version-gate friendly.
--transform-yappears in--help, so an
orchestrator can probe the help text before relying on the flag. This matters:
a ≤ 1.15.x engine treats unknown flags as ignored positionals and exits 0 —
your captions would import recentered with no error. - 🔒 Byte-identity locked. A new oracle test freezes the exact v1.15.0
segment bytes (ids normalized) for the flag-absent path. - 🧪 494 tests (+16). Typecheck clean; lint baseline unchanged.
Usage
# batch captions pinned mi-bas, cloning the draft's existing caption style
$ capcut-david import-captions <draft> captions-styled.json \
--clone-style --color "#FFFFFF" --transform-y -0.4
# preflight an orchestrator (version gate): is the flag supported?
$ capcut-david --help | grep -q -- "--transform-y" || echo "engine too old"
Compatibility
- No
--transform-y→ byte-identical output to 1.15.0 (oracle-locked). - A later
restylegrafts the keys present in the preset'ssegmentblock onto
every caption segment — a position-bearing preset (one whosesegment.clip
carries a transform, like the vault gabarits) then overwrites the imported y.
A preset withoutsegment.clip(e.g. everymake-presetoutput, which emits
segment: {}) leaves the imported position intact. Put the position-bearing
import-captionsLAST in the caption chain, or keep carrying the position via
a clip-bearing restyle preset. - One deliberate side effect:
--transform-yis parsed globally, soadd-text
andset-textno longer swallow a literal--transform-y <n>into the rendered
text — the pair is consumed and ignored (and a non-numeric next token dies).
On ≤ 1.15.x the same invocation visibly garbled the caption text. The vertical
position flag onadd-textis and remains--y. - No other schema, dependency or behavior change; read commands untouched.