# 1.14.0 — `make-preset`: generate a restyle preset for any font

Minor release. One new **read-only** verb, zero changes to existing behavior. It is
the generation cousin of `query`: where `query` answers *"what's this font's
resource_id?"*, `make-preset` hands you a ready-to-use **bare-font** `restyle`
preset for it.

## The problem it solves

To restyle captions onto a new font you needed a hand-crafted preset JSON — digging
the font's `resource_id`, `.ttf` path and catalogue `title` out of CapCut internals
(the exact pain the S1649 #8 investigation mapped). `make-preset` reads all of that
from a draft you already have and emits the preset for you.

## Highlights

- 🅰️ **`capcut-david make-preset --font <name|resource_id>`** — finds the font in your
  drafts library and emits a preset ready for `restyle --preset`.
- 🔡 **Name substring** match (case-insensitive); a **purely numeric** `--font` is
  matched as an **exact `resource_id`**.
- 📁 **Source = your drafts library** (`defaultProjectsRoot()`, override `--drafts`).
  Zero new dependencies — the full font block already lives in any draft that uses
  the font, so no CapCut-cache / SQLite reading.
- 🎯 **Bare font.** The preset carries ONLY the font identity (no stroke/shadow/size).
  The `fonts[]` entry is copied **verbatim from the draft** (path normalized,
  `request_id` cleared) so CapCut's font dropdown resolves the name.
- 🧹 **Smart dedupe.** Same font seen as both a local copy and a catalogue download
  collapses to the catalogue truth (`source_platform == 1`). Two *different* fonts
  matching your term → **ambiguous**: it lists the candidates and refuses to guess.
- 🛟 **Refuses the unbuildable.** A local-only font (no `resource_id`) can't yield a
  resolvable catalogue preset → exit 2 with a clear message.
- 💾 **`--out <file>`** writes the preset file; otherwise it rides in the JSON
  envelope. `-H/--human` prints a one-line summary / candidate list.
- 👀 **Read-only.** Not a write command — no `.bak`, no CapCut-closed guard.
- 🧪 **458 tests** (+25). Typecheck clean; `make-preset.ts` lint-clean.

## Usage

```
# 1. generate a preset for a font you've used before
$ capcut-david make-preset --font SpeedLines --out speedlines.json

# 2. apply it to every caption of a draft
$ capcut-david restyle "<...>/com.lveditor.draft/<draft>" --preset speedlines.json
```

```
$ capcut-david make-preset --font derstil --human          # one-line summary
$ capcut-david make-preset --font 7605981975781887248      # exact resource_id
$ capcut-david make-preset --font line                     # ambiguous → lists candidates
```

JSON envelope (`capcut-david/make-preset@1`):

```json
{
  "type": "capcut-david/make-preset@1",
  "ok": true,
  "font": {
    "title": "SpeedLines",
    "resource_id": "7605981975781887248",
    "font_path": "C:/.../Cache/effect/7605981975781887248/.../font.ttf",
    "source_platform": 1,
    "from_drafts": ["niche_pc_..."]
  },
  "ambiguous": false,
  "candidates": [],
  "written": "speedlines.json",
  "preset": { "text_material": { "...": "..." }, "content_template": { "...": "..." }, "segment": {} }
}
```

## Why drafts-library, not the CapCut cache

The complete font block — including the catalogue `title`, `source_platform`, and the
`.ttf` cache path — already lives in any draft that uses the font. Reading CapCut's
resource-SDK SQLite cache would add a native dependency to a deliberately
zero-dependency engine and couple to an undocumented cache layout, for no extra
coverage: a catalogue font you can use is one you've applied at least once, which
writes it into a draft.

## The dropdown "System" caveat (context)

A freshly engine-restyled catalogue font shows the correct name in CapCut's dropdown
**iff** its catalogue entry is in CapCut's font-panel cache — otherwise CapCut shows
"System" (cosmetic; render/export are always correct). This is CapCut-internal state,
not something any draft file controls. `make-preset` copies the draft's real
`fonts[].title` + `source_platform` so the preset is as resolvable as a native pick.
See the CapCut-CaptionStyling skill's `CapCutGotchas.md` for the full root-cause.

## Migration

**None.** `make-preset` is a brand-new verb; nothing else changed. It reads no project
path — it takes `--font` and scans the library.

## Compatibility

- CapCut ≥ 5.x desktop (Windows + macOS) — unchanged.
- Node `>= 18` — unchanged.
- Runtime dependencies: zero — unchanged.

## Roadmap (1.x — non-binding)

The validate→fixer family is complete; `query` + `make-preset` form the
catalogue/discovery pair. Backlog S1649 is closed (the restyle "System" dropdown
quirk was root-caused as a CapCut-internal cache limitation, not an engine bug).
