{"id":"c70238bb-0d04-4a7e-9483-6e2bc6fa396d","slug":"malik1942-product-film","kind":"skill","name":"product-film","summary":"Agent skill: turn screen recordings into scored product films — AVFoundation pipeline, no ffmpeg, no editor","owner":"Malik1942","repoUrl":"https://github.com/Malik1942/product-film","license":"MIT","licenseTier":"permissive","trust":"community","stars":4,"match":null,"fewStars":true,"format":"skill","createdAt":"2026-08-05T02:45:01.000Z","addedAt":"2026-10-14T06:13:38.804Z","logoUrl":"https://avatars.githubusercontent.com/u/220207332?u=82dc237b3fae7e9d9b49489c88921a329e1d794a&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["design-media","data-analytics"],"tags":["ai-agents","avfoundation","product-demo","promo-video","screen-recording","swift","video"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-17T08:50:39.998Z","sample":false,"url":"https://conduits.dev/tools/malik1942-product-film","language":"Swift","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# product-film\n\n**An agent skill that turns screen recordings into scored, verified product films.** One `SKILL.md` plus plain Swift scripts, nothing agent-specific inside — it runs on any agent that reads the format (Codex, Cursor and Claude Code today).\n\nPoint your agent at your product — an iOS app, a website, a desktop app, or a Figma prototype — and it gains the full production pipeline, **self-contained in this one install**: from capturing the takes to delivering the final scored MP4, nothing else to download.\n\n- **Capture** — record the takes itself (ScreenCaptureKit recorder, staging checklists, pre-roll gate), or start from recordings you already have\n- **Measure** — find the real interaction times in the footage, so every cut lands where something actually happens\n- **Cut** — splice the beats, never mid-animation\n- **Composite** — camera moves and click cues; device mockup for mobile, Screen-Studio-style full-bleed for desktop\n- **Stitch** — scenes into acts, with title cards and transitions between them\n- **Score** — a synthesized, license-free soundtrack matched to the film's stated vibe\n- **Audit** — the final cut graded scene-by-scene against the approved script\n\nAll of it on AVFoundation alone: no ffmpeg, no video editor, no cloud rendering. Every stage is a plain Swift script you can also run by hand.\n\n| Mobile path — from the Oryne launch film | End card — in the product's brand font |\n|---|---|\n| ![mobile](docs/example-mobile.png) | ![card](docs/example-card.png) |\n\n| Desktop path — from the [Inkwork](https://malikzhang.com/inkwork) film |\n|---|\n| ![desktop](docs/example-desktop.png) |\n\nEvery frame above is unretouched pipeline output from two shipped films. The desktop shot is full-bleed, Screen-Studio style: the page fills the canvas at every zoom level, so no black margin or card edge can slide into frame. Desktop apps and landscape Figma prototypes get the same treatment.\n\n## Why it exists\n\nAgent-cut product films tend to fail the same few ways: trims made from *intended* timings instead of measured ones, cuts landing mid-animation, reveals with no visible click, zooms focused on the wrong thing, watermarked stock audio, cards carrying the last project's copy.\n\nEvery rule in this skill is a codified rejection from a real film delivery. The playbook is the accumulated taste; the verification gates — frame-scan before trimming, full-resolution card reads, a gap audit delivered with every render — are what keep quality stable from one session to the next.\n\n## Requirements\n\n- macOS with Xcode Command Line Tools (`swift` on PATH; `python3`, stock on macOS, for the camera-plan derivation)\n- Any agent that reads `SKILL.md` skills — e.g. [Codex](https://developers.openai.com/codex), [Cursor](https://cursor.com), [Claude Code](https://claude.com/claude-code)\n- For iOS Simulator capture: Xcode (`DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer`)\n\nThat's everything — no companion downloads; capture tools ship in `scripts/` (compiled once on first use with `swiftc -O`, as the docs instruct the agent).\n\n## Install\n\n**curl** — installs for every supported agent (one real copy, the rest symlinked to it):\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/Malik1942/product-film/main/install.sh | bash\n```\n\nNarrow it to the agents you use, or scope it to a single repo:\n\n```bash\n./install.sh --codex --cursor\n```\n\n```bash\n./install.sh --project\n```\n\n**git / gh** — clone straight into a directory your agent reads. `.agents/skills/` is the shared cross-agent convention, so it's the widest default:\n\n```bash\ngit clone https://github.com/Malik1942/product-film.git ~/.agents/skills/product-film\n```\n\n| Skills directory | Read by |\n|---|---|\n| `~/.agents/skills/` | Codex, Cursor |\n| `~/.claude/skills/` | Claude Code, Cursor |\n| `~/.cursor/skills/` | Cursor |\n| `~/.codex/skills/` | Cursor, older Codex builds |\n\nThe `~/` paths make the skill available in every project; swap `~/` for `<repo>/` to scope it to one repo and commit it with the project. Any of these directories can be a symlink to a single checkout — that's what `install.sh` sets up, so one `git pull` updates every agent. There's no registration step anywhere: agents discover `SKILL.md` on their own.\n\n## How to prompt\n\n**1 — Start with one sentence: the goal, and where the footage is (or will come from).**\n\n```text\nMake a 60-second promo film for my app. Raw recordings are in ~/Desktop/MyAppTakes.\n```\n\n```text\nFilm my website at example.com into a Screen-Studio-style demo.\n```\n\nIf your agent supports explicit invocation you can also name it directly — `$product-film` in Codex, `/product-film` in Cursor and Claude Code.\n\n**2 — It answers with a film script to fill in, not a render.** That's the approval gate: no expensive renders until the direction is agreed. The script is six blocks — all the information the film is built from (fill-in template: [`references/writing-the-script.md`](references/writing-the-script.md)):\n\n| You provide | Example |\n|---|---|\n| Product & surface | iOS app on a simulator · website URL · Figma prototype link |\n| Placement & length | landing page · ~60s · 2560×1440 |\n| Vibe | \"calm and premium, like a sundown ambient track — avoid busy percussion\" |\n| Scenes, one idea each | the click to show · the payoff to read (exact text/number) · the data that must exist first |\n| Words | opening tagline · title-card texts · end-card line + CTA |\n| Brand | card font (`.ttf` or installed name) · accent colors · logo |\n| Sound | a reference track or mood — otherwise synthesized to the vibe |\n\nSkip the vibe and it will ask — offering two or three named directions to pick from — because vibe drives the cut rhythm, camera energy, card tone and the entire score.\n\nA filled script is short. Compressed from a real film:\n\n```text\nFILM: Inkwork promo   SURFACE: website — malikzhang.com/inkwork   PLACEMENT: landing page\nCANVAS: 2560x1440     LENGTH: ~45s\nVIBE: playful and energetic — plucked, moving; biggest moment: the Arcade reveal\nSCENES:\n1. Create a QR — interaction: type URL, click Create · payoff: branded QR + \"Scannable\" · data: none · ~8s\n2. Styles — interaction: click style cards · payoff: QR restyles live in the Proof panel · ~8s\nTITLE CARDS: before 2 — \"BREAK THE GRID\"\nEND CARD: logo + \"DESIGNED AND BUILT BY MALIK\"\nBRAND: default font, accents FFEE51,0EA5E9   SOUND: playful, bell motif at the reveal\n```\n\n**3 — Approve the script and the pipeline runs**: capture → measure → cut → composite → stitch → score → mux. Every delivery arrives with frame verification **and a scene-by-scene gap audit** — each scene of the actual rendered file graded against the script (MET / PARTIAL / CONTRADICTED / MISSING / DEVIATES) from extracted frames, editing gaps fixed before delivery, capture gaps named plainly.\n\n**4 — Style it, any time — before the first render or after the tenth.** Direction works at two levels, and the skill knows the difference:\n\n- **Vibe-level** cascades to every surface — edit rhythm, camera energy, cards, animation, score move together:\n  `\"Make it warmer and more playful.\"` · `\"Calmer, more premium.\"`\n- **Scoped** touches only what you named, and asks before spreading:\n  `\"Make the logo gold on the end card.\"` · `\"Slow the title card entrance.\"` · `\"White accent bars on the cards.\"`\n\nThe skill's built-in taste (zoom-through transitions, click cues, pacing) is a default, not a cage — explicitly ask for anything and it applies to your film. Only the engineering gates don't bend: measured trims, frame verification, the gap audit, and no watermarked audio.\n\nFixing a delivered cut works the same conversational way:\n\n```text\nThe page turn in scene 2 feels laggy and the zoom focuses on the wrong thing. Fix both.\n```\n\n## What's inside\n\n| Path | What |\n|---|---|\n| `SKILL.md` | Triggers, pipeline order, non-negotiables, symptom→fix table |\n| `references/playbook.md` | Stage contracts, script arguments, camera grammar, iron laws |\n| `references/capture-protocol.md` | Capture stage: staging checklists (sim / web / Figma proto), per-take protocol, HiDPI maths |\n| `references/writing-the-script.md` | The six-block film-script contract + fill-in template |\n| `references/gap-audit.md` | The mandatory per-render audit format |\n| `references/scoring.md` | Stage-7 score engine: the `score.json` schema, the five presets, the vibe→contract map (+ `acestep-setup.md` for the Tier-B ACE-Step path) |\n| `scripts/` | The whole pipeline: capture (sckrecord, rollgate, autoplan, conform), measure (scan, diffscan ×2), cut (condense), composite2, stitch, score engine (score-render + score-dsp, Tier-B fit-score, probe gate), mux, title/end cards |\n| `assets/iphone-mockup.png` | Neutral device frame (generated, MIT-licensed) |\n\nScripts come in three classes. **Utilities** run as-is with explicit arguments: `swift scripts/mux.swift film.mp4 score.m4a out.mp4`. The **stitch template** is copied into your project and edited in-file — the clip order *is* the interface. The **score engine** (`score-render` + `score-dsp`, plus Tier-B `fit-score`) is compiled with `swiftc -O` and driven by a small per-film `score.json` — you write the JSON, not the synth code. No script contains machine-specific or `/tmp` paths, and nothing depends on which agent is driving: every stage runs by hand from a shell.\n\n## Device frames\n\nThe bundled frame is a clean generated bezel (safe to redistribute). For a photorealistic device, drop in any bezel image with a transparent screen cutout — e.g. Apple's official product bezels from [Apple Design Resources](https://developer.apple.com/design/resources/) (check Apple's usage terms):\n\n```bash\nFRAME_PNG=/path/to/bezel.png SCREEN_RECT=x,y,w,h swift scripts/composite2.swift ...\n```\n\n## Capture-only sibling\n\nEverything needed for the full pipeline — **capture included** — ships in this repo; install it and you're ready, nothing else to download. The capture stage (staging checklists, per-take protocol, `sckrecord`, `autoplan.py`) is also published standalone as **[screen-recording](https://github.com/Malik1942/screen-recording)** for people who only want clean product captures without the film pipeline. If both are installed, they compose; neither requires the other.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) — mechanics changes are normal PRs; taste-law changes go through the ratification gate described there.\n\n## License\n\nMIT — see [LICENSE](LICENSE). Brand fonts are never bundled; supply yours per project via `FONT_FILE`.\n\n---\n\nBuilt by [Malik Zhang](https://malikzhang.com).\n"}