SuperAPI AI Directory

aip-reference-style

Design & creation

View repository

Updated 10-31 18:42

About this skill

Edit in a reference video's style

A reference sets three things in the user's edit: the captions, the motion graphics (titles, text overlays, stickers, cards, animated graphics, and camera treatments such as punch-ins, shakes and flashes), and the transitions between beats. Everything else follows the AI Producer skill: its settings for a new project, its rough cut, its sound effects, its research and its delivery. Its aesthetic rules hold here as over every fine cut: the reference decides how things look, move and cut, and the rules decide what the edit shows, how much of it and whether it reads, with floors the reference keeps. You copy the reference's style, never its content.

Get the reference

  • A video file the user gave you is the reference as it is. Images the user gave you are a reference of stills: put them in one new directory, in the order given.
  • A link to a post on Instagram, TikTok or YouTube: get it as soon as you have it, while the user's footage is still being prepared, with start_link_download and the link. AI Producer fetches the video and answers with its download_url; when it answers state: "downloading" instead, call it again with the same link after poll_after_seconds, which joins the same download rather than starting another. Download download_url before download_expires_at into a new directory outside render-engine/, saved under the answer's file_name, and from then on it is a video file the user gave you; a link that expired is fetched again with the same call. Never download the post any other way, such as with a downloader you find installed.
  • A preset: read it with get_reference_preset and its preset_id. A preset the user names or describes is matched by its name and look in list_reference_presets, which is also what you show, by name and look, a user who asks which presets there are. Download the answer's folder.download_url before download_expires_at, check the file's sha256 and size against the answer, and unpack it into a new directory outside render-engine/. That directory is what reference_frames.py writes for the preset's video, with its caption-kit/ already made when the preset shows captions and its style pack when it was built with one, so you do not run the script for it, and a preset has no video to download or open. A link that expired is fetched again with the same call. When the call answers that no presets are published, or that the preset is unknown or withdrawn, tell the user in one sentence and ask for a reference video, a link or images instead.
  • A directory that holds reference-index.json is a reference already read: a preset's unpacked folder, or the folder of a reference an earlier edit read. Use it as it is, as a preset's folder, without running the script on it.
  • A request sent from the AI Producer web page carries its reference in get_web_assignment's answer: a preset with its preset_id and catalogue_version, both passed to get_reference_preset; a link, downloaded as above; or a video or images, each file with a download_url. Download each file before its link expires, reading the assignment again for fresh links, and use them as a video file or a reference of stills. Start on the reference as soon as the assignment says it is ready, without waiting for the footage, as the AI Producer skill's section on a request from the web page says.
  • When start_link_download cannot get the post, tell the user in one sentence what its code means and what to send instead: link_private, the post is private, so ask for the video file; link_region_blocked, the post is not available from AI Producer's servers, so ask for the file; link_age_restricted, the post is age-restricted, so ask for the file; link_unavailable, the post was removed or is not available, so ask for another link or the file; link_too_long, a reference may be at most the answer's max_duration_seconds long, so tell the user that limit and ask for a shorter clip or the file; platform_busy, the platform is turning downloads away for now, so they can send the link again later or send the file; link_unsupported, only Instagram, TikTok and YouTube links work, so ask for one of those or the file; link_download_busy, they started too many link downloads, so say when they can try again from retry_after_seconds, and that the file works now. link_download_unavailable is a passing problem on AI Producer's side, not the post's: call it once more with the same link, and only when that answers the same ask for the file. link_download_failed, and any other refusal or error, asks for the video file.
  • What reading the reference and matching its captions need on the machine, ffmpeg, python3 and uv, you set up yourself without asking the user: install what is missing. A missing tool is never a reason to stop or to edit without the reference.

Start preparing the user's own footage first, as the AI Producer skill says: its upload and preparation run while you get and read the reference. Open the project's progress page as soon as project_id returns, as the AI Producer skill's progress section for this host says, before the reference is read: the reading takes a while, and the user watches the project from the start.

Read the reference

When the reference's folder holds style/style.md, the reference is already read into a style pack: read style.md and the visuals and templates it names first, and make no caption kit for it. A whole pack (its first line Pack: whole) is the entire reading: open nothing else of the folder unless style.md leaves a question open, which one contact sheet, strip or keyframe then answers. An edit's pack (Pack: edit) holds every caption treatment but only the graphics one earlier edit used, so read the contact sheets and transition pages below as well, for the graphics and transitions it does not hold. Everything below about reading the stills is otherwise for a reference without a pack.

Run reference_frames.py with the reference video, or the directory of reference images, and a new directory outside render-engine/; a preset's unpacked folder is that directory already. For a video it writes the stills you read the style from and reference-index.json, which names each file with the times it covers:

  • contact-sheet-NN.jpg: the analyzed span at two frames a second, each frame labeled with its time.
  • transitions-NN.jpg: one row per change of shot between beats, twelve frames a second across the cut, so the way one beat hands to the next is visible. Each boundary in the index carries a kind read from the frames' brightness and change: cut (one frame to the next, nothing between), flash (the frames brighten across the cut, toward white or a colour, as in a flash or a light leak), or blur (both shots smear where they meet, as in a whip or a blur).
  • strips/beat-NN.jpg: each beat at up to four frames a second, for how a treatment enters, moves and leaves.
  • keyframes/beat-NN.jpg: one larger frame per beat, for type, color and layout detail.

A long reference is analyzed in windows: its opening and windows spread evenly over the rest, up to the script's budget, so the sample keeps the reference's own mix of quiet and busy stretches. partial and analyzed in the index say when that happened, and cuts_per_minute gives the cutting rate over the whole reference beside the rate in the windows; read proportions from the windows against those rates.

For a directory of images it writes stills/still-NN.jpg, one per image in order, and an index whose kind is images: stills show no beats, cuts or transitions.

Read every contact sheet first, then every transition page, then the strips and keyframes of the beats that carry a distinct treatment; of a reference of stills, read every still. These stills are input analysis: they are never staged, uploaded, or drawn into the edit.

When the reference shows captions, pick by their time labels, while you read the contact sheets, what the captions will be matched against: a moment for each distinct treatment the captions use, two to four in all (a plain line, an emphasized word, a stacked line, a colour or a fill the picture shows through), each paired with a moment of the same shot without a caption, or with the least of one; the moment just before a caption arrives; and the band of the frame height the captions sit in. Run the script again on the same directory with them, --caption-kit <caption>:<clean>,... --band <top>:<bottom> --entry <seconds>. It writes caption-kit/: those frames at the reference's own resolution, and kit.jpg, their caption bands side by side above the band frame by frame as a caption arrives. Read kit.jpg once and replace a pair that does not show what you picked it for. The kit is everything the captions are matched against, once the cut is final, as Matching the captions says. A reference that shows no captions gets no kit. A reference of stills names stills by number instead of times, --caption-kit <still>[:<still>],... --band <top>:<bottom>: each still that shows a caption, with a still of the same shot without one when the images include it, and no --entry, since a still shows no caption arriving. A preset's folder already holds its kit when the preset shows captions; make no other.

What to copy

  • Captions. The reference's caption look, matched against the caption kit and written as caption moments as Matching the captions says, with the dynamic caption skill's timing and mounting. A reference with no captions of its own still gets captions, in that skill's plain look, which you write yourself once the cut is final, with no kit and no subagent.
  • Motion graphics. Each kind of treatment the reference uses, with its layout (overlay, seat, full cover, split), typography, palette, shapes and motion. Recreate each one as a composition under the composition contract, filled with the user's own content: their words, their facts, their imagery. A kind the style pack holds starts from its template, filled as the style pack says. When the folder is a reference the user brought, keep each kind you write in its pack, as the style pack's step 4 says, with one comparison against its visual, and write its style.md once the caption report is in, or once the graphics are written when the reference shows no captions.
  • Transitions. How beats hand to each other: a hard cut, a punch-in, a flash, a whip or slide, a blur, a mask, and how text and graphics leave as the next beat arrives. Read each boundary's kind against its row, and look for what it cannot name, such as a slide, a mask or a punch-in. Use the transitions the reference uses, about as often as it does. A transition the reference does not show is not used: no flash, shake, whip or glitch it lacks, whatever the creative direction would otherwise add, and a reference that only cuts hard gets hard cuts.
  • Cutting rhythm. How often the picture changes: cuts_per_minute.whole is the reference's rate. When the reference cuts between shots and the user's footage is one continuous shot, carry that rhythm with reframes of the speaker: at a sentence or phrase boundary, change hard to another framing - full frame, a tighter one at 1.3x or more on the face, a recomposition toward one side - as a zoom effect host with no ramp in or out, held for the stretch it frames. Count the visual moments' own changes toward the rate, and alternate framings so no two in a row match. A reframe never removes speech: what is said is the rough cut's alone.
  • Proportion. Use each treatment about as often, for about as long, and over about the same share of the runtime as the reference does, measured against the user's own length. Keep the reference's balance between the speaker on screen and graphics on screen, within the floors the aesthetic rules' rhythm section sets. Its most striking element is not a reason to run it across the whole edit, and one it shows once stays a one-off.

A reference of stills shows the captions, the motion graphics, the palette and the layout, but no transitions, cutting rhythm, motion or timing. Copy what the stills show, in about the balance between speaker and graphics they show, and the AI Producer skill's creative direction decides the rest.

Leave the reference's content out:

  • its brands, logos, people, product screens, screenshots and words;
  • anything that belongs to the platform or the recording rather than the edit: play buttons, progress bars, usernames, watermarks, the platform's own captions and stickers, a cursor or a recording frame.

When a treatment carries a kind of material the user's footage lacks, such as a screen recording or a product shot, find the user's own equivalent through the AI Producer skill's visual research or author it, or give that treatment a different payload from the user's content.

The user's frame decides geometry. When the user's footage differs from the reference in orientation, framing or length, keep each treatment's character and place it with the framing skill.

Where the reference and the AI Producer skill's creative direction disagree about captions, motion graphics or transitions, the reference wins. Everything the reference does not show, the direction still decides. The user's own words outrank both, and the aesthetic rules outrank the reference in the order they give.

Working files

Keep the files you make while reading the reference and matching the captions in directories you create for them, and name them by their full paths. Never delete with a shell wildcard, such as rm -f out/* or rm frames/*.png: Claude Code stops for the user's approval on every such delete, whatever its permission mode, and refuses it where no one can answer. To redo a set of files, write the new set into a new directory and use that one, or overwrite each file by its name; a script of yours that replaces its own output deletes only the files it wrote, by name, from inside the script.

Matching the captions

This section is for a reference that shows captions. When the style pack holds its caption treatments, they are matched already: once the cut is final, run caption_cues.py as below and write every caption moment yourself from the templates, as the style pack says, with no subagent and no kit; stage the faces style.md names; then compare one page that mounts them over a frame of the user's footage, as step 3 below says, and publish. Everything else in this section is for a reference whose pack holds no captions.

Its captions are written as soon as the cut is final, which it is once the rough cut is written in your local render-engine/ directory: graphics, framing and sound never move the words, and nothing needs publishing first. Run caption_cues.py on that directory then, as the dynamic caption skill says, and keep the rows it prints in a file. Where the host can start a subagent, as Claude Code's Task tool does, start one in the background with this brief and nothing more, its placeholders filled in, and go on with the motion graphics while it works:

Write the caption moments that the section "Matching the captions" in <this skill's SKILL.md> describes, and nothing else. The caption kit is <the frames directory>/caption-kit/, <a frame of the user's footage> is a frame of the user's own footage at the canvas size, and the rows caption_cues.py printed for the final cut are in <the rows file>. Write the caption moments under <the render-engine directory>/compositions/ and their font files under its public/fonts/, keep each matched part in <the frames directory>/style/captions/ as references/style-pack.md says, never writing its style.md, and leave every other file alone. Stop when the caption moments match the kit, and report each caption host to mount, writing the same report to <the report file> as your last step. Ultrathink.

Mount and publish what it reports, unchanged, with your first publication after it reports; if the cut changes after you sent the rows, send it the new rows. If the rest of the edit is done before it reports, wait for the report file in steps of at most two minutes, each a command that returns as soon as the file appears, rather than ending your turn: a step taken after about five idle minutes pays for your whole context again. Elsewhere write the captions yourself at that point, the same way.

The captions are matched against the caption kit alone. Read kit.jpg once; the kit's frames are the only reference pictures you open, and only to compare with or to measure as below: no contact sheet, strip or keyframe, and never the reference video. Of this package, read this skill, the dynamic caption skill, the composition contract, the style pack and the aesthetic rules, and no other file, scripts included. caption_compare.py does the plumbing, run as uv run --with fonttools python <the script> <command>: fonts <name> lists the installed faces of a family, specimen <out.png> <frame> --text "<words>" --crop X,Y,W,H --size <px> <family> sets the words in every face of the family under that part of the frame, extract <font file> <index> <out.ttf> splits one face out of a collection, and compare <out.png> <frame>=<page> --crop X,Y,W,H renders a page at the frame's size beside the frame, cropped to that part at full resolution. Replace a page, an image or a caption moment you rebuild as Working files says.

Each part of the caption, a line, an emphasized word or a fill, is its own moment host over the frame, each host its own layer as in the edit, and a part that blends with the picture carries its blend on its host, as the composition contract says. What matches on the page then goes into the edit unchanged but for its words and times.

  1. Settle the faces. specimen sets a kit caption's own words in every installed face of the families you name, under that caption; pick each part's face from that one image, and extract it as a font file.
  2. Match the look like for like before writing any caption moment: a page at the kit frame's size that mounts, over that pair's clean frame, the caption's parts built the way the edit's will be, with the kit caption's own words. Run compare with the caption frame, which sets the two side by side cropped to the caption band at full resolution, read that image, change what differs, and run it again, until the two cannot be told apart, for each pair in the kit. Face, weight, size, tracking, colour and position are read from that image, never measured. A look includes how its text sits on the picture: solid over it, letting the picture show through it, or blending with it. A part that lets the picture through or blends does so over any picture, so draw it that way, never as colours that copy what one frame shows behind it, and keep one styling for each treatment across every kit pair that shows it. Only for such a part, or one the image leaves open, measure how its pixels follow the picture beneath, and where the kit has no clean frame of its shot, make one from the caption frame by masking the caption and filling it from around it. Measure nothing else. Keep each part that matches as style/captions/<treatment>-<part>.html in the reference's folder, as the style pack says, and describe each treatment in the report the way style.md's Captions section does; the edit writes style.md from that report.
  3. Write every caption moment from the rows the same way, taking how a caption arrives from the kit's last row (a kit from stills has none, so the dynamic caption skill's entry stands), then compare a page that mounts one of them over the user's frame, beside that frame, to see that it reads there and that a part that lets the picture through or blends still does over that picture.

The pages render locally with a headless browser (one the host's sandbox stops from starting usually starts with Chrome's --single-process). They are reference analysis before publication: they are never staged or uploaded, and they are not an inspection of the edit.

The captions' fonts are font files staged with them, since the export machine has none of this computer's fonts: a face installed here is staged from its own file, a collection such as .ttc split to the face the captions use, because the workspace takes .woff, .woff2, .ttf and .otf, and only a face you cannot get as a file takes its closest open family. Staging a face installed here is this product's own decision, and whether a face's license allows it is reviewed outside the edit, so the captions never swap a face for an open family over its license. Their colour is drawn in CSS, never with the reference's own pixels.

Tell the user

In the message that says the run has started, say in one or two plain sentences what you are taking from the reference - the caption look, the kinds of graphics, the way beats change - and that the content will be their own. Name no file, tool, frame count or window. A reference you could not get or read is said once, in the same plain words, with what the user can send instead.