Every release
The release loop: one editable take becomes the demo, the listing and the social cuts, and the next version re-renders it.
A release needs media: the demo, the store listing, a card for the feed, a what's-new clip. vosso treats that set as one editable document rendered to many destinations, so shipping the media becomes part of shipping the release, and the next version is mostly a re-render.
The loop, once per release:
- 1
Keep the script in the repo
actions.jsonis the recording script: the click path through your product, written once and committed next to the code it demonstrates. It is the next release's script too. - 2
Re-record, keep the cut
Shellvos record --actions actions.json --out take --strict vos plan take --reuseRecord the same script into the same take directory: the footage is replaced and the cut survives (
doc.prev.json).--reusethen re-times that cut onto the new recording. The recorder wrote down when every step ran, so a zoom you placed on the checkout button follows the checkout button, even when a new banner shifted everything down; the look copies over; the automatic camera re-plans. Whatever could not follow, a moved step or a control that left the UI, is named in the report rather than guessed at, and you fix just those. - 3
Cut it, deliver it
Cut by exception over what the planner proposed, then render the whole destination set in one pass:
Shellvos deliver take-v2 --to cws,producthunt,linkedin,og --release "v2.1"The verb renders and verifies, and composes nothing: the still moments come from the script's steps (the end of a gesture, or of the wait after a click that navigates), the cards render from the poster documents beside the take (
poster/<class>/doc.json, one per aspect class, each a plain take whose card sits where the poster wants it and ends on a freeze whose start is the still), and the cuts play whatvos planproposed into the document in one animation vocabulary: the card's enter, the templates the recipe names (an end card from your shelf, or the officialEnd cardtemplate from vos.so when the recipe leavesendCardon: the house one as clips after the footage), a caption per step, a music bed and click sounds where the channel plays sound. A poster is made withvos plan <poster take> --style <a poster on your shelf> --headline "…", which copies the layout and types the words in, then pushed like any take. Every asset is verified against its channel's spec andkit.jsonrecords the set;vos validate kit/kit.json --picturethen reads what each asset looks like (a blank moment, a crop where a card was asked for, a headline cut at the edge, white words on a paper ground) and says it with a code and a fix. See Store listings for the store half in detail. - 4
Push it, labelled for the release
Shellvos push take-v2 --label "v2.1 launch" --note "what shipped, one line"The push creates a version named for the release, and the watch page always plays the latest one, so a shared link never goes stale. The take, the script and the kit are the release's media source, kept.
The repo is the home
Keep the release's media source next to the code it demonstrates:
media/
actions.json the recording script (steps carry ids and captions)
doc.json the signed-off cut of the last release
BRAND.md the brand kit: colours, faces, the look (vos brand writes it)
LAUNCH.md per-channel house rules and the release's words (headline, kicker, music)
kit.json what the last release shipped, verifiedThe platform mirrors it: vos push versions the take on your shelf,
vos pull brings studio edits back, and media/vos.json tracks which
vos the pushes land on. After a release, commit the updated doc.json
so the next re-record has the cut to carry.
Run it on every pull request
The whole loop is headless, so CI can produce the release's media, and a pull request can carry it the way a preview deployment carries a site: one comment with the watch page and the kit, updated in place on every push, so reviewers, QA and marketing sign off on a link. The vosjs/action action does the loop:
name: release media
on:
pull_request:
push:
tags: ['v*']
permissions:
contents: read
pull-requests: write
jobs:
media:
runs-on: ubuntu-latest # ships Google Chrome, which mp4 renders need
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- uses: vosjs/action@v1
with:
key: ${{ secrets.VOS_API_KEY }} # mint a content key at /app/apiIt records media/actions.json, carries media/doc.json onto the new
footage, renders cws,og,github by default (channels: widens it; the cards
render from the poster/ documents committed beside the script),
re-measures the kit with vos validate,
pushes the take labelled for the release, attaches the kit to the run, and
keeps the comment. Without the key nothing is pushed and the comment says
so. The same run on a tag is the release.
Or write the workflow by hand
The steps the action runs, if you would rather own them (the same
VOS_API_KEY secret):
name: release media
on:
push:
tags: ['v*']
jobs:
media:
runs-on: ubuntu-latest # ships Google Chrome, which mp4 renders need
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- run: npm i -D @vosjs/cli
- name: record the shipped product
run: npx vos record --actions media/actions.json --out /tmp/take --strict --json
- name: carry the committed cut onto the new footage
run: npx vos plan /tmp/take --reuse --from media/doc.json --json
- name: render the destination set
run: npx vos deliver /tmp/take --to cws,og --release "${{ github.ref_name }}" --json
- name: push the take, labelled for the release
env:
VOS_API_KEY: ${{ secrets.VOS_API_KEY }}
run: |
cp media/vos.json /tmp/take/vos.json || true
npx vos push /tmp/take --label "${{ github.ref_name }} launch" --note "CI release media" --yes --json
- uses: actions/upload-artifact@v4
with: { name: release-kit, path: /tmp/take/kit }--strict fails the job on a broken selector instead of shipping around
it, and a push against a stale base fails with the changelog of what
changed on the shelf, so a human race never resolves silently. The
flagged list from --reuse prints in the job log; anything named there
is the release's real to-do.
Hand it to your agent
The whole loop is agent-shaped. npx skills add vosjs/skills installs the
launch-kit skill, and a message like "we're shipping v2.1 on Friday, make
the demo and the Chrome Web Store listing" is enough: the agent records,
cuts, delivers and pushes, and you fine-tune the result in the studio.
Related
- Store listings for the exact-size still loop.
- Publish and share for the watch page a release links to.
- CLI verbs for every command this page uses.