About session-story
session-story is a skill that turns an agent’s real conversation history with a user into a 40–70-second film. It uses verbatim dialogue, a room based on known details, and an original score, with user review and approval required before rendering.
Key features
- 01Harvest local conversation history
- 02Build a film from events in session order
- 03Use verbatim dialogue and real timestamps
- 04Design a room from known user details
- 05Compose a score for the film timeline
- 06Require line review before rendering
Use cases
- 01Make a film about a user’s typical agent session
- 02Visualize the work and exchanges in a conversation
- 03Create a reviewed film from user-provided transcripts
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ heygen-com/ hyperframes-community-skills --skill session-storyAfter installing, type/session-storyin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
assets/engine/index.htmlLICENSE-ClaudeAnimationBaseNOTICE.mdstory.jsassets/engine/kit/clawd.jsconfig.jscore.jshf-bridge.jstimeline.jsassets/engine/scenes/cast-custom.jscompile.jsdesk.jsdirector.jspaper.jsprops-custom.jsprops.jsassets/example/score.pystory.jsonreferences/cast.mdmotion.mdroom.mdscore.mdsources.mdstory.mdscripts/harvest.pynew-project.mjspackage-lock.jsonpackage.jsonschedule.mjsscripts/score/build.shDetails
From the project READMESession story
The agent reads its own history with its user, finds their routine, and turns one typical session into a 40 to 70 s film, in the order it happened:
- Story: the user's verbatim words arriving as objects, and the agent's own replies going back. The window and the wall clock follow the session's real time.
- Room: decorated from what the agent knows about its user.
- Score: composed by the agent against the film's own timeline.
Write story.json and the engine does the choreography. Nothing on screen is invented: every line is a quote, and
the user approves every line before a frame is rendered.
When to use / when not
- Use when a user asks their agent for a film of their work together, and the agent has real history with that user: local transcripts, or messages the user pastes in.
- Do not use for someone else's history, a team's shared logs, marketing with made-up quotes, or anything the user won't review. With no history at all, ask the user for a session's messages. Never invent quotes.
Requirements and side effects (complete list)
- Tools: Node 22+, Python 3.9+ (standard library only),
ffmpegon PATH, and the HyperFrames CLI pinned tonpx --yes [email protected](downloaded from the npm registry on first use). - Setup (once, manually):
sh scripts/setup.shrunsnpm cifrom the committed lockfile: p5 2.3.3 (LGPL-2.1), p5.brush 2.2.3 (MIT), @fontsource/permanent-marker 5.3.0 (Apache-2.0). Read-only downloads from npm. - Score renderer: on macOS,
swift(Xcode Command Line Tools) plays the score through Apple's built-in General MIDI bank. Elsewhere,fluidsynthwith a General MIDI soundfont you set asSOUNDFONT. Neither downloads anything. - Reads (local only, after the user says yes): the agent's own transcripts,
~/.claude/projects/<project>/*.jsonl(Claude Code) and~/.codex/sessions(Codex), for the current project unless the user allows--all-projects. Also the agent's memory and instruction files for the room. Nothing is uploaded. - Writes:
session-story-candidates.json(harvest) and everything inside the project folder you create. Both hold the user's words: never commit or share them. - Network at build time: none. Pass
--describe falseto everysnapshot, as shown below: withGEMINI_API_KEYset,snapshototherwise sends frames (the user's words) to Gemini. Render locally: the page paints with WebGL. - No credentials, no paid calls.
Workflow
- Setup:
sh scripts/setup.sh(once). - Ask first. Tell the user you'll read your local history with them to find the session, and wait for a yes.
- Harvest:
python3 scripts/harvest.py --project <their project folder> --out <scratch>/candidates.jsonprints the routine and lists sessions, most typical first.--session <id>(with the same--project) prints one in order, with local times and your replies. Per references/sources.md. - Scaffold:
node scripts/new-project.mjs <dir>. Everything you write from here lives in<dir>. - Story: take a typical session and write
<dir>/story.jsonbeat by beat, in the order it happened, with each beat's real time, per references/story.md. The user's lines are verbatim spans; your replies are your own words from that session. Setscreento what their work looks like, and pick the ending their sessions have.node scripts/schedule.mjs <dir>checks it: run it after every edit. - Room: fill the slots from what you know about the user, per references/room.md. Draw a
custom prop in
<dir>/scenes/props-custom.jswhen the library has nothing true to them. If you are not Claude, draw yourself: references/cast.md. - Privacy gate: show the user one table of every on-screen line (hook, nameplate, each quote, each reply, each
prop and why), each with its source. Take their edits, get an explicit yes, then set
"approved": true. Until then every frame carries a DRAFT stamp. - Design pass: run the
snapshotcommandschedule.mjsprints. Look at every frame: quotes legible, props where they belong, nothing covering a message. Show the user the contact sheet. - Score: write
<dir>/score/score.pywith your own theme, key and palette, per references/score.md. Thensh <dir>/score/build.sh. It fails on dead air. - Render: from
<dir>:npx --yes [email protected] check, thennpx --yes [email protected] render --fps 24 --crf 12 -o renders/session-story.mp4. - Check the render: its length must match
schedule.mjs. Pull a frame at each key moment (ffmpeg -ss <t> -i renders/session-story.mp4 -frames:v 1 renders/check-<t>.png) and look at them. Then hand it to the user to watch with sound.
The example (node scripts/new-project.mjs <dir> --example, then schedule.mjs <dir> --example) is the reference
film: a real session between Claude and the skill's author, who makes videos. It shows the format, not the shape of
your film. schedule.mjs refuses it without --example, so it can't stand in for your user's story.
Verify success
schedule.mjsexits 0 and prints no warnings.hyperframes checkpasses. p5.brush logs WebGLuniformwarnings, which are harmless.- The design-pass frames show every quote legible, and match the beat table.
score/build.shends withok: no dead air, and the score's length matches the film's.- The render is the length
schedule.mjsprinted, has an audio track, and its frames at the key moments match the design pass. - Failure path to test: a story that opens on a reply, or has a quote over the limit, makes
schedule.mjsexit 1 and name the beat.
What the engine owns
The motion is physical and already tuned: glide paths, the fold, the throw, the swing, the bonk and the wingbeats.
Change the story, the room, the cast and the score. Leave the choreography in scenes/director.js and
scenes/compile.js alone unless you are fixing a bug. The motion rules are in
references/motion.md.