# 1.7.0 — engine hardening: absolute paths + "CapCut is open" guard

Minor release. Fixes the two most expensive CLI footguns documented across the CapCut skills — no new feature surface, just an engine that stops shooting you in the foot on Windows.

## Highlights

- 🪟 **Absolute source paths work on Windows.** `add-audio` / `add-video` used `path.startsWith("/")` to decide "absolute vs relative". On Windows an absolute path is `C:\…` — it doesn't start with `/`, so it was treated as relative and glued onto the cwd → `ENOENT`, or the asset silently never made it into `assets/`. Now `path.resolve()` (correct on Windows + POSIX) resolves the source and `path.basename()` extracts the filename. The skill's phase-5 workaround ("pass files RELATIVE to the cwd") is no longer needed.
- 🔒 **"CapCut is open" preflight guard.** Writing a draft while CapCut is running is the #1 gotcha in every CapCut skill: CapCut keeps the draft in memory and **overwrites it on close**, silently throwing away your CLI edits (and, via `Timelines/`, desyncing the render). Every write command now refuses to run when CapCut is detected, with a clear message and a `--force` escape hatch. This re-instates the preflight the retired Python patchers had (`tasklist` + `CapCut.exe` check) that the TypeScript engine had lost.
- 🧪 **Byte-identity preserved.** The absolute-path fix only changes behavior for absolute inputs (which used to fail). A relative input that already worked produces a byte-for-byte identical draft — locked by test.
- ✅ **279 tracked tests** (265 prior + 3 absolute-path + 11 guard). Typecheck + lint clean.

## What changed

### #1 — Absolute path resolution (`add-audio` / `add-video`)

```
# Before (Windows): C:\clips\voice.mp3 → not "/"-prefixed → cwd + "/" + "C:\clips\voice.mp3" → ENOENT
# After:            path.resolve(arg) → absolute kept as-is, relative joined to cwd (Win + POSIX)
```

The stored `material.path` is, and always was, `assets/<type>/<filename>` inside the draft — so relative inputs are unchanged. Absolute inputs now correctly copy the source into the draft's `assets/` and reference it there.

### #2 — "CapCut is open" guard

```
$ capcut-david restyle my-draft --preset cc-derstil.json
{"error":"CapCut is running — close it before writing (or pass --force). CapCut overwrites the draft on close, silently discarding CLI edits."}

$ capcut-david restyle my-draft --preset cc-derstil.json --force   # bypass
```

- **Guarded:** `add-text`, `add-audio`, `add-video`, `add-effect`, `import-captions`, `restyle`, `set-text`, `shift`, `shift-all`, `speed`, `volume`, `trim`, `opacity`, `add-keyframe`, `ken-burns`, `apply-template`, `batch`, `cut`, `psycho-build`, `register`.
- **Not guarded:** read-only commands (`info`, `tracks`, `segments`, …) and `init` (creates a brand-new draft — no open-draft conflict).
- **Detection:** `tasklist /FI "IMAGENAME eq CapCut.exe"` (Windows) / `pgrep -il capcut` (macOS/Linux). **Fail-open**: if the probe can't run or finds nothing (e.g. CI runners), the command proceeds — the guard never breaks automation.
- **Escape hatch:** `--force` flag or `CAPCUT_DAVID_FORCE=1` env var.

## Migration

**No code changes required.** The guard is a refusal-by-default that aligns with the documented workflow (keep CapCut closed through the whole CLI chain; open it only at the end). Automation that legitimately writes while CapCut is open should pass `--force` or set `CAPCUT_DAVID_FORCE=1`.

Once on 1.7.0, the CapCut skills can drop the phase-5 "pass files RELATIVE to the cwd" footgun note.

## Compatibility

- CapCut ≥ 5.x desktop (Windows + macOS), JianYing 6+ unsupported — unchanged.
- Node `>= 18` — unchanged.
- Runtime dependencies: zero — unchanged.
- `add-text` / `import-captions` / `restyle` output byte-identical to 1.6.0; only absolute-path inputs to `add-audio`/`add-video` change (they used to fail).

## Roadmap (1.x — non-binding)

Unchanged from 1.0.0:

- `1.x.0` — `capcut-david query` (animation / sticker / effect / filter catalogue lookup)
- `1.x.0` — `capcut-david validate <project>` (schema-invariant linter)
- `1.x.0` — JianYing 6+ research; `psycho-build` dynamic audio ducking
