# 1.13.0 — `query`: catalogue lookup by name → resource_id

Minor release. One new **read-only** verb, zero changes to existing behavior. It
answers the question every draft builder hits: *"I know the effect/font is called
'Dissolve' / 'VHS Horror' / 'CC-DerStil' — what's its `resource_id` so I can inject
it?"*

## The problem it solves

To add an effect, filter, transition or font to a draft you need its long numeric
`resource_id` (e.g. `6724846004274729480`), not its human name. Until now you had
to open an old draft and dig through `materials.*` by hand. `query` indexes every
draft you already have and lets you search by name.

## Highlights

- 🔍 **`capcut-david query <term>`** — searches the whole CapCut drafts library
  (every draft under the projects root) and returns matching effects, filters,
  transitions and fonts with their `resource_id`/`effect_id`.
- 🎯 **`--kind effect|filter|transition|font`** — narrow to one kind.
- 📁 **`--drafts <dir>`** — point at a specific library root (default =
  `defaultProjectsRoot()`).
- 🔡 **Case-insensitive substring** match on the item name.
- 📦 **Dedupe + provenance.** Identical resource across drafts collapses to one
  result whose `from_drafts[]` lists every draft it appears in. Local fonts (no
  `resource_id`) dedupe by name + path and report `resource_id: null` + the
  `font_path`.
- 👀 **Read-only.** Not a write command — no `.bak`, no CapCut-closed guard; safe
  to run any time, even with CapCut open.
- 🖨️ **`-H/--human`** renders a `KIND / NAME / RESOURCE_ID / FROM_DRAFTS` table;
  default output is the JSON envelope.
- 🧪 **433 tests** (+34). Typecheck clean; `query.ts` lint-clean.

## What counts as each kind

| Kind | Source |
|------|--------|
| `effect` | `materials.effects` entries where `type != "filter"`, plus all `materials.video_effects` |
| `filter` | `materials.effects` entries where `type == "filter"` |
| `transition` | `materials.transitions` |
| `font` | `materials.texts[].fonts[].title` (with its `resource_id`); else the local `font_path` → name via `deriveFontName` and `resource_id: null` |

`deriveFontName` strips the file extension and one trailing weight/variant token
(plus the `VariableFont_wght` pair) from a closed set — never an arbitrary token,
so `PlayfairDisplay-VariableFont_wght.ttf` → `PlayfairDisplay`, `Roboto-Bold.ttf`
→ `Roboto`, but `CC-DerStil.ttf` stays `CC-DerStil`.

## Usage

```
$ capcut-david query dissolve                       # all kinds, default library
$ capcut-david query vhs --kind effect              # only effects
$ capcut-david query playfair --kind font --human   # human table
$ capcut-david query dissolve --drafts /path/to/lib # custom library root
```

JSON envelope (`capcut-david/query@1` — flat, no `next`):

```json
{
  "type": "capcut-david/query@1",
  "results": [
    {
      "kind": "transition",
      "name": "Dissolve",
      "resource_id": "6724846004274729480",
      "effect_id": "6724846004274729480",
      "category_name": "Transitions",
      "font_path": null,
      "from_drafts": ["transitions-draft"]
    },
    {
      "kind": "font",
      "name": "PlayfairDisplay",
      "resource_id": null,
      "effect_id": null,
      "category_name": null,
      "font_path": "/.../PlayfairDisplay-VariableFont_wght.ttf",
      "from_drafts": ["my-draft"]
    }
  ]
}
```

Human table:

```
KIND        NAME            RESOURCE_ID          FROM_DRAFTS
font        CC-DerStil      7457793217560318481  ken-burns-draft
transition  Dissolve        6724846004274729480  transitions-draft
```

**Exit codes:** `0` for any valid query — **including zero matches and an empty
library**; `2` only on operational failure (drafts root missing / not a directory,
or every draft's `draft_content.json` failed to parse); `1` for usage errors
(missing `<term>`, invalid `--kind`). A partially-broken library is `0` — malformed
drafts are silently skipped and scanning continues.

## Migration

**None.** `query` is a brand-new verb; nothing else changed. It reads no project
path — it takes a search term and scans the library.

## Compatibility

- CapCut ≥ 5.x desktop (Windows + macOS), JianYing 6+ unsupported — unchanged.
- Node `>= 18` — unchanged.
- Runtime dependencies: zero — unchanged.

## Roadmap (1.x — non-binding)

The validate→fixer family is complete and unified under `validate --fix`; `query`
adds catalogue discovery alongside it. Remaining backlog: the restyle "System"
font-dropdown cosmetic quirk.
