mirror of
https://github.com/storytold/filmcraft.git
synced 2026-11-02 18:09:21 +00:00
6.9 KiB
6.9 KiB
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), ../pdfcraft (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.
- Read
plan/STATUS.md(current milestone, next unchecked task, blockers). Public:ROADMAP.md, thendocs/gaps.md(ranked shortfalls) anddocs/roadmap.md(current focus). - Read the task in
plan/execution-plan.md§3, the relevant section ofplan/architecture.md, and the README/docs of the crate you touch. Public:docs/architecture.md,docs/contributing.md,docs/testing.md. Visual/behaviour reference:plan/premiere/(local only, never committed). - Follow the autonomous operation protocol (
plan/execution-plan.md§7; public summary:docs/agents.md§5–7). Don't stop to ask unless it lists the decision as the user's.
Non-negotiables
Read AGENTS.md first; its rules override everything here.
- Never crash (
AGENTS.md§0). People depend on FilmCraft; a crash loses their work, so this outranks feature work. Nounwrap/expect/panic!/unreachable!/todo!/unimplemented!orunsafeoutside tests: returnResult<T, E>and propagate with?(ok_or,let … else,if let). Treat every number from media, project files, presets or CLI/MCP/control params as hostile:get()instead of[i], checked/saturating math, no division by possibly-zero values, capped allocations, bounded recursion.lock().unwrap_or_else(PoisonError::into_inner); background jobs run undercatch_unwind. The panic hook + UIcatch_unwind(crates/ui-egui/src/crash.rs) are the last-resort guard, not a licence. Every crash fix gets a regression test that panicked before. In particular (§1): never use Adobe iconography, images or any other Adobe asset. Every asset must be openly licensed (OSS / public domain / Creative Commons, or original work by a contributor) and must have a<file>.attributionsidecar plus an entry inATTRIBUTION.md.cargo xtask assetsenforces this. - Fonts live in storytold/craft-fonts, never in this repo (no new font files here;
AGENTS.md§1.9). Build with them:git clone https://github.com/storytold/craft-fonts ../craft-fonts && CRAFT_FONTS_DIR="$PWD/../craft-fonts" cargo run -p filmcraft(crates/text/build.rsembeds them asfilmcraft_text::fonts::CRAFT_FONTS, used for Japanese in the UI and titles). Unset,CRAFT_FONTSis empty and everything must still build, test and run; never add craft-fonts to aCargo.toml. Tests on its glyphs skip when it is empty, so run the gates with and withoutCRAFT_FONTS_DIRwhen you touch fonts. - Clean-room. Never read/disassemble anything inside Adobe app bundles (names/listings only). Never copy Adobe icons, presets, LUTs, fonts. Never copy GPL/LGPL/AGPL code (FFmpeg, x264, x265, MLT, Kdenlive, Shotcut, Olive, LAME…). ffmpeg/ffprobe run only as external test oracles / fixture generators — never linked or shipped.
- Pure Rust in the product. OS media APIs only via Rust bindings in
crates/platform(hardware decoding; the one crate allowedunsafe, seeAGENTS.md§0.3 anddocs/adr/0001-platform-ffi.md), optional, behind traits, with our decoders as the fallback. - Layering (
docs/architecture.md§1, enforced bycargo xtask layers): nothing below L5 depends on egui/eframe/winit/rfd/cpal. L0 codec/container crates depend only onfilmcraft-bitstream. - Exact time: all time is
filmcraft_time::Tick(254 016 000 000/s). Never use f64 seconds for edit math. - Time goes through
chrono(workspace dependency). Never hand-roll UTC/calendar conversion (days-to-date algorithms, leap-year math); a crate owns only its output format string. The one exception is range extension: past the years chrono can represent, shift the date by whole 400-year Gregorian cycles (146,097 days, after which the calendar repeats), let chrono compute the month and day, and add the cycles back to the year (splitting seconds into hours, minutes and seconds is plain arithmetic). - Everything is a command (
crates/engine): id, label, menu path, shortcut, params, enabled(), run(). UI, CLI, control channel and MCP all dispatch by id. - Everything is agent-drivable: every interactive widget registers an automation id; UI state is serde so the control channel can read/set it.
- Quality gates before every commit:
cargo fmt --check,cargo clippy --workspace --all-targets -- -D warnings,cargo test --workspace,cargo xtask layers,cargo xtask assets,cargo xtask wasm(checks L0–L4 crates).cargo xtask ciruns them all. - New workspace crates must include
[lints] workspace = trueinCargo.tomlto inherit[workspace.lints]. Production crate roots must declare the required crate-level lint attributes before modules or other crate items; crate-level//!documentation may precede them. - Commits: one task id per commit (
M2.4: CABAC residual decoding). Only green states. End messages with the attribution line required by the environment.
Running and looking at the app
cargo run -p filmcraft -- --control 9876opens the desktop app with the JSON-lines control server (seedocs/control-protocol.md).- For UI work, look at the result: drive via the control channel and take
ui.screenshot, compare withplan/premiere/screenshots/(maintainer-local; seedocs/agents.md§3). - Parallel agents: separate git worktrees and
CARGO_TARGET_DIR=target/agent-<name>; keep everyCargo.tomlvalid at all times (thecrates/*glob means one broken manifest breaks everyone). - Test fixtures: generate with ffmpeg into
target/fixtures/(never commit media). Seedocs/testing.md.
CI workflows
- Workflows in
.github/workflows/call the shared workflows instorytold/craft-common-actionsat@main, with their inputs and secrets. No other jobs: if no shared workflow does what's needed, it doesn't go here. - Don't add or change CI in a feature or fix PR. If the existing workflows can't build or test a change, link an existing craft-common-actions issue or PR, or open a new issue, or a PR only for a small fix that is safe for every app and does not increase CI time.
- Some workflow files here still run their own jobs. Don't add to them. Moving a job into craft-common-actions is its own task, never part of another PR, and the job stays here until a shared workflow runs it.