Docs: releasing guide, CLI export options, README and CLAUDE.md drift (#85, #86, #87, #88, #99)

- docs/releasing.md (#99): release.yml points readers to it twice and it didn't exist. Written from
  the workflow and packaging scripts as they are (macOS, Windows x64/x86/arm64, Linux x86_64/aarch64
  with the glibc 2.35 floor, web; draft release, secrets).
- filmcraft-cli help (#86): export lists --scale, --quality, --no-audio and --queue, and apv among
  the formats.
- README (#87): more than 650 engine commands (671 today), not about 135.
- README (#88): the web line says the browser app ships with every release and links docs/web.md.
- CLAUDE.md (#85): the Illustrator-class sibling is ../vectorcraft (formerly DrawCraft).

Fixes #85
Fixes #86
Fixes #87
Fixes #88
Fixes #99

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Thomas 2026-10-07 10:49:08 -04:00
parent 3628bbe744
commit fa67dfa372
4 changed files with 143 additions and 5 deletions

View File

@ -1,6 +1,6 @@
# FilmCraft — instructions for agents
FilmCraft is a clean-room, open-source, pure-Rust non-linear video editor targeting Adobe Premiere Pro parity (and beyond). Native on macOS, Windows, Linux; web via WASM. Sibling of `../photocraft` (Photoshop), `../printcraft` (Acrobat) and `../drawcraft` (Illustrator), with the same conventions.
FilmCraft is a clean-room, open-source, pure-Rust non-linear video editor targeting Adobe Premiere Pro parity (and beyond). Native on macOS, Windows, Linux; web via WASM. Sibling of `../photocraft` (Photoshop), `../printcraft` (Acrobat) and `../vectorcraft` (Illustrator; formerly DrawCraft), with the same conventions.
## Start every session here
`plan/` is maintainer-local (gitignored, not in the repo). Each step names the public equivalent to use if you don't have it.

View File

@ -220,7 +220,7 @@ Import merges the document's bins, media and sequences into your project as one
## Built for agents
Every menu item, button, slider and drag in FilmCraft is a **command** with an id, typed parameters and an enabled state. There are about 135 engine commands so far, with the rest of Premiere's catalogue on the way. The UI, the CLI, a JSON control channel and an **MCP server** all dispatch the same commands, so Claude or any agent can cut, trim, grade, mix and export exactly the way a person does. The UI can also be driven at the level of mouse and keyboard: every widget has an automation id, and agents can click, drag, type and take screenshots.
Every menu item, button, slider and drag in FilmCraft is a **command** with an id, typed parameters and an enabled state. There are more than 650 engine commands (`filmcraft-cli commands` lists them), with the rest of Premiere's catalogue on the way. The UI, the CLI, a JSON control channel and an **MCP server** all dispatch the same commands, so Claude or any agent can cut, trim, grade, mix and export exactly the way a person does. The UI can also be driven at the level of mouse and keyboard: every widget has an automation id, and agents can click, drag, type and take screenshots.
```jsonc
// over the control channel (JSON lines on TCP) or as MCP tool calls
@ -238,7 +238,7 @@ The trailer and the grades in these screenshots were built exactly this way, by
## Everywhere
- **Native** on macOS, Windows and Linux, with a native macOS menu bar.
- **The web:** every crate up to the engine compiles to `wasm32`; the browser front end is next.
- **The web:** the same engine and UI run in the browser via WebAssembly (`apps/filmcraft-web`, see [docs/web.md](docs/web.md)); every release ships it as `filmcraft-web-<version>.zip`.
- **Swappable UI.** The interface is one crate (`ui-egui`) over the engine, so a different front end can replace it without touching editing logic.
<br>

View File

@ -27,12 +27,16 @@ SUBCOMMANDS
inspect [project|sequence] project tree or active sequence as JSON (default: both)
import <file>... import media into the project
export <out> [--preset name] [--format f] [--range r] [--start s --end s] [--settings json]
[--scale f] [--quality 0-100] [--no-audio] [--queue]
export the active sequence and wait for it to finish: with an
export preset (`export --list-presets`; built-in or the user's), or
a format (h264|prores|dnxhr|mjpeg|mxf-op1a|mxf-opatom|png|tiff|bmp|gif|wav|aiff, guessed
a format (h264|prores|dnxhr|apv|mjpeg|mxf-op1a|mxf-opatom|png|tiff|bmp|gif|wav|aiff, guessed
from the extension); --range entire|inOut|workArea, or a custom
range in seconds; --settings is ExportSettings JSON merged over the
preset; --queue adds to the export queue and runs it instead
preset; --scale renders at a fraction of the frame size (0.5 =
half); --quality 0-100 for the formats that take one; --no-audio
leaves the sound out; --queue adds to the export queue and runs it
instead
export --list-presets [query] list export presets (name, category, format) as JSON
render --seconds S --out f.png [--scale 0.5] render one Program frame to PNG
probe <media> [--image-sequence]

134
docs/releasing.md Normal file
View File

@ -0,0 +1,134 @@
# Releasing FilmCraft
Every push to the `release` branch runs `.github/workflows/release.yml`. The workflow builds
installers for macOS, Windows and Linux, plus the web build, and creates or updates a **draft**
GitHub Release named `FilmCraft v<version>`. Nobody sees a draft until a maintainer publishes it.
User-facing names say **FilmCraft**. Files, binaries and ids stay lowercase
(`filmcraft-<version>-<platform>-<arch>.<ext>`, `ai.storyteller.filmcraft`).
## Cutting a release
1. **Bump the version** on `main`. It lives in exactly one place, `[workspace.package] version`
in the root `Cargo.toml`; every crate inherits it and the packaging scripts read it from there:
```sh
cargo xtask version # prints the current version, e.g. 0.2.1
cargo xtask version set 0.3.0 # or 0.3.0-rc.1; updates Cargo.toml and Cargo.lock
```
Commit the change (`Cargo.toml` + `Cargo.lock`) through the normal review flow, as a
`Release: FilmCraft v0.3.0` commit whose message says what changed for users.
2. **Merge `main` into `release`** (or fast-forward it) and push. The workflow starts by itself.
3. **Wait for the draft.** When every job is done (macOS notarization is the slow part), the
Releases page has a draft `FilmCraft v0.3.0`, targeting the pushed commit, with every artifact
and `SHA256SUMS.txt`. The notes are generated from the merged pull requests.
4. **Check it.** Download an installer or two and read the job summaries. A `::warning::` there
means a signing secret was missing and that artifact is unsigned.
5. **Publish** the draft in the GitHub UI. Publishing creates the `v0.3.0` tag. A version with a
pre-release suffix (`-rc.1`) is marked as a pre-release.
Pushing to `release` again before you publish rebuilds the same draft and replaces its assets.
Once the draft is published, the workflow refuses to touch that version again: bump it first.
**Test runs:** *Actions › Release › Run workflow* runs the whole pipeline by hand. The optional
`version` input (such as `0.3.0-rc.1`) overrides `Cargo.toml` for that run only; each build job
applies it with `cargo xtask version set` before building. The jobs run in the `release`
environment, which only the `release` branch can use, so pick that branch in the dialog.
## What gets built
| Platform | Artifacts | Built on |
|---|---|---|
| macOS 11+ (universal: Apple silicon and Intel) | `filmcraft-<v>-macos-universal.dmg`, `filmcraft-cli-<v>-macos-universal.zip` | `macos-15` |
| Windows x64 | `filmcraft-<v>-windows-x64.msi`, `filmcraft-<v>-windows-x64-portable.zip` | `windows-latest` |
| Windows x86 (32-bit) | `filmcraft-<v>-windows-x86.msi`, `filmcraft-<v>-windows-x86-portable.zip` | `windows-latest` |
| Windows on ARM64 | `filmcraft-<v>-windows-arm64.msi`, `filmcraft-<v>-windows-arm64-portable.zip` | `windows-latest` (cross-compiled) |
| Linux x86_64 | `filmcraft-<v>-linux-x86_64.{AppImage,deb,rpm,tar.gz}` | `ubuntu-22.04` |
| Linux aarch64 | `filmcraft-<v>-linux-aarch64.{AppImage,deb,rpm,tar.gz}` | `ubuntu-22.04-arm` |
| Web | `filmcraft-web-<v>.zip`, a static site (see [`packaging/web/README.md`](../packaging/web/README.md)) | `ubuntu-latest` |
`filmcraft --version` and `filmcraft-cli --version` print the version from `Cargo.toml`.
**Fonts.** Every build job checks out [craft-fonts](https://github.com/storytold/craft-fonts) at a
pinned commit (the `ref:` of its craft-fonts checkout step, marked `# bump deliberately`) and builds
with `CRAFT_FONTS_DIR` and `CRAFT_FONTS_REQUIRED=1`, so releases embed its Japanese fonts and fail
rather than ship without them (the web build embeds only the UI font, to stay small). The packages
carry each embedded font's licence (`copy_font_licences` in `packaging/env.sh`). Bump the pins
deliberately, in every job at once.
### macOS
`packaging/macos/package.sh` builds `aarch64-apple-darwin` and `x86_64-apple-darwin` with
`MACOSX_DEPLOYMENT_TARGET=11.0`, joins them with `lipo` and assembles `FilmCraft.app`:
- `Info.plist` is generated from `Info.plist.in` (bundle id `ai.storyteller.filmcraft`, the
version and the build commit).
- **Signing** uses the hardened runtime and a secure timestamp, with the entitlements in
`entitlements.plist`. The Developer ID certificate is imported into a temporary keychain by
`packaging/macos/import-cert.sh`.
- **Notarization:** the app is sent with `xcrun notarytool submit`, then the ticket is stapled
and checked with `stapler validate`. The app goes on a DMG (`hdiutil makehybrid`), which is
signed and notarized too. The universal `filmcraft-cli` is signed the same way, zipped, and the zip is notarized.
Locally, without certificates, the script signs ad hoc and skips notarization, which is enough to
check the bundle and the DMG on your own Mac (`packaging/macos/package.sh`).
### Windows
`packaging/windows/package.ps1 -Arch x64|x86|arm64` builds with `+crt-static`, so neither the MSI
nor the portable zip needs the Visual C++ redistributable.
- `filmcraft.wxs` (WiX) is a per-machine install into Program Files with a Start Menu shortcut and
an App Paths entry (Win+R `filmcraft`). Same-version upgrades are allowed, so release candidates
replace each other.
- The ARM64 build is cross-compiled on the x64 runner. `.github/workflows/windows-arm64.yml`
installs that MSI on a Windows 11 ARM64 runner, runs `filmcraft-cli --version` natively and
uninstalls.
- **Signing:** `packaging/windows/sign.ps1` signs the executables and then the `.msi` with
`signtool`, using whichever material is present: a `.pfx` certificate (`WINDOWS_CERTIFICATE`,
base64, and `WINDOWS_CERTIFICATE_PASSWORD`) or Azure Trusted Signing (the `AZURE_*` secrets). With
neither, it warns and leaves the files unsigned, so test builds still produce installers.
### Linux
`packaging/linux/package.sh` builds the release binaries and packages them as an AppImage, a
`.deb` and an `.rpm` (with [nfpm](https://nfpm.goreleaser.com), from `nfpm.yaml`) and a plain
`.tar.gz` tree. The packages install both programs, the desktop entry, the AppStream metainfo, the
icons and the licence files.
The jobs run on `ubuntu-22.04`, the oldest GitHub-hosted image, so the binaries only need
glibc 2.35 or newer: Ubuntu 22.04+, Debian 12+, Fedora 36+ and RHEL 10. The deb (`libc6 (>= 2.35)`)
and the rpm (`glibc >= 2.35`) both declare that floor, so older systems refuse the install. Moving
the job to a newer image raises the floor, so do it deliberately and update `nfpm.yaml` with it.
After packaging, the job prints the `.deb`'s metadata and contents, runs `ldd` on the binary and
runs each AppImage with `--version`.
`packaging/linux/flatpak/ai.storyteller.filmcraft.yml` is a Flatpak manifest (its header says how
to build it). The release doesn't build a Flatpak; the workflows only check the manifest's id.
### Web
The web job builds `apps/filmcraft-web` with `cargo xtask web` (the `wasm-bindgen` CLI must match
the crate's version exactly, `WASM_BINDGEN` in `xtask/src/main.rs`) and zips the static site with
`packaging/web/package.sh`. [`packaging/web/README.md`](../packaging/web/README.md) covers hosting.
## The draft release
The last job waits for every build, downloads their artifacts, writes `SHA256SUMS.txt` and creates
the draft `FilmCraft v<version>` with notes generated from the merged pull requests. If the draft
already exists, it replaces its assets and keeps it a draft. If that version is already published,
the job fails and asks for a version bump (`cargo xtask version set`).
## Secrets
All jobs run in the `release` environment, which only the `release` branch can use and which holds
the signing secrets. Every secret is optional: a missing one produces unsigned artifacts and a
warning, never a failed build.
| Secret | Used for |
|---|---|
| `APPLE_CERTIFICATE`, `APPLE_CERTIFICATE_PASSWORD`, `KEYCHAIN_PASSWORD` | the Developer ID certificate (base64 `.p12`), imported into a temporary keychain |
| `APPLE_ID`, `APPLE_PASSWORD`, `APPLE_TEAM_ID` | notarization (`APPLE_PASSWORD` is an app-specific password) |
| `WINDOWS_CERTIFICATE`, `WINDOWS_CERTIFICATE_PASSWORD` | Windows signing with a `.pfx` |
| `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SIGNING_ENDPOINT`, `AZURE_SIGNING_ACCOUNT`, `AZURE_CERT_PROFILE` | Windows signing with Azure Trusted Signing |