# 1.14.1 — `sync-timelines` reconciles the guid's `draft_info.json`

Patch release. One **bugfix**, no API changes, no new verbs. `sync-timelines` now
repairs the timeline mirror CapCut actually reads on the **first open** of a
CLI-built draft, so audio and captions added after the build are no longer silently
lost.

## The bug it fixes

A draft built in the CLI and **never opened in CapCut yet** keeps its timeline mirror
in `Timelines/<guid>/draft_info.json` — CapCut only materialises
`Timelines/<guid>/draft_content.json` once it has opened the draft. But `saveDraft`
writes **only** the root `draft_content.json`. So audio/captions added after the
initial video build (e.g. `add-audio`, `import-captions`) landed in the root only:

1. CapCut opens the draft → reads the **video-only** guid `draft_info.json`.
2. The audio + caption tracks are absent → they never render.
3. On close, CapCut rewrites the root `draft_content.json` back to video-only — the
   edits are gone for good.

`sync-timelines` was meant to repair exactly this kind of divergence, but its
`MIRROR_FILES` list reconciled only `draft_content.json` + `template-2.tmp`. In the
pre-open state the guid has **no** `draft_content.json`, so the fixer touched nothing
that mattered and the stale `draft_info.json` survived. `draft_info.json` was an
**oversight** in that list — not a deliberate exclusion (only the `.bak` files and the
patch journals `mini_draft.json`/`patch.json` are excluded on purpose).

Root cause confirmed by a filesystem A/B repro: priming the guid's `draft_info.json`
to the full root content makes CapCut open with audio + captions intact; leaving it
video-only reproduces the loss.

## Highlights

- 🔧 **`sync-timelines` now reconciles `Timelines/<guid>/draft_info.json`** to the root
  `draft_content.json` bytes — the file CapCut reads on first open of a CLI-built draft.
- 🎯 **Scope = the guid's `draft_info.json` only.** The **root** `draft_info.json` (an
  inert legacy sibling — CapCut does not read it as authority) is **never** touched. The
  root-siblings pass still refreshes the root `template-2.tmp` only.
- 📣 **Data-loss transparency extended.** The stderr `WARNING` for a divergent
  overwrite now also fires when the guid's `draft_info.json` is overwritten (previously
  only `draft_content.json`), so a silent rewrite can't slip by.
- 🛟 **Same safety net, unchanged.** Timestamped `.synced-<epoch>.bak` before every
  overwrite, skip-if-absent, skip-when-byte-identical, per-guid isolation, root draft
  read-only.
- 🧪 **464 tests** (+6). Typecheck clean; changed files lint-clean.

## Usage

No usage change. Run it as before, after patching a CLI-built draft and before opening
it in CapCut:

```
$ capcut-david sync-timelines "<...>/com.lveditor.draft/<draft>"
```

Pre-open drafts (guid has `draft_info.json` but no `draft_content.json` yet) are now
repaired; post-open drafts (guid has both) reconcile both files to the root ("root
wins"), as before.

## Migration

**None.** Behavior is strictly additive: a file that was being skipped is now
reconciled. Existing flows are unchanged; re-running `sync-timelines` on an
already-synced draft is a byte-identical no-op.

## Compatibility

- CapCut ≥ 5.x desktop (Windows + macOS) — unchanged.
- Node `>= 18` — unchanged.
- Runtime dependencies: zero — unchanged.
- Output byte-identity contract (v1.3.0) — unchanged; the full golden suite stays green.

## Roadmap (1.x — non-binding)

The validate→fixer family is complete; `query` + `make-preset` form the
catalogue/discovery pair. This patch closes a data-loss gap in `sync-timelines` for
CLI-built, never-opened drafts.
