AGENT SKILL

psychopomp

Make explainer reels and deterministic motion graphics with Psychopomp: walkthrough videos of pull requests, code changes, protocols, or lifecycles, with GPU Stage choreography, callouts, rolling numbers, sequence diagrams, animated diffs, and optional ElevenLabs or Fish Audio narration.

License 许可
MIT
所属仓库
mikker/dotfiles
最近更新
2026-11-10
Stars
★ 116
Forks
4

01 前言 Front Matter

name
psychopomp
description
Make explainer reels and deterministic motion graphics with Psychopomp: walkthrough videos of pull requests, code changes, protocols, or lifecycles, with GPU Stage choreography, callouts, rolling numbers, sequence diagrams, animated diffs, and optional ElevenLabs or Fish Audio narration.

02 资源文件 1

03 SKILL.md 正文

Psychopomp explainer reels

An explainer reel is several independently authored Scene Plans joined on one clock: behavior stories on the GPU Stage (orbs, cards, beams, packets, camera, bloom), pinned Callouts, Rolling Numbers, changes as animated Stepped Diffs, captions in a terminal voice, and optional spoken narration. When narrated, every visual beat waits for a phrase in the transcript, so re-voicing re-times the film automatically.

The working examples are in scenes/pr-walkthrough: src/flagship.rs (#50825 as a Stage film that zooms into its code), src/stop_stage.rs (#50042 combining Stage, Callouts, Rolling Number, and a Zoom into an annotated code diff), and src/lib.rs (the five-PR reel with sequence diagrams). Copy their shape; do not start from a blank crate. Component payloads, channels, and commands live in SCENE_PLANS.md ("Make A Narrated Explainer Reel") and terms in CONTEXT.md; read both before authoring. Engineering rules are in AGENTS.md.

Steps

  1. Establish the facts. For each change, read the actual diff and PR description (gh pr diff, gh pr view) and write one sentence each for the broken behavior, the fixed behavior, and the change. Done when every claim you will narrate is traceable to code, a test, or a reproduced run; mark anything you could not verify and keep it out of the script.

  2. Write the script as scenes/<name>/narration/script.json, one clip per part: intro, then per change <slug>-before, <slug>-after, <slug>-code, then outro. Follow STORY.md when writing it. Done when each clip is under about 30 seconds spoken and every planned visual beat has a distinct anchor phrase in it.

  3. Voice it (optional). Draft first with no credentials (--draft uses macOS say), or synthesize final narration with ElevenLabs (engine: "elevenlabs", default model eleven_v4) or Fish Audio (engine: "fish"):

    {
      "engine": "elevenlabs",
      "model": "eleven_v4",
      "voice": "<elevenlabs-voice-id>",
      "settings": { "stability": 0.5, "similarity": 0.7 },
      "clips": [
        { "id": "change-before", "text": "[warm, conversational voice] ..." }
      ]
    }
    
    # Draft (no API key required)
    bun scripts/narrate.ts scenes/<name>/narration/script.json --draft
    
    # ElevenLabs (requires ELEVENLABS_API_KEY and script.voice)
    ELEVENLABS_API_KEY=... bun scripts/narrate.ts scenes/<name>/narration/script.json
    
    # Fish Audio (requires FISH_AUDIO_API_KEY)
    FISH_AUDIO_API_KEY=... bun scripts/narrate.ts scenes/<name>/narration/script.json
    

    scripts/narrate.ts normalizes loudness, transcribes word timings with Whisper, and writes <id>.mp3, <id>.words.json, and narration.json. When switching voices or engines, rebuild the Scene Plan against the new word timings.

    Or declare the narration in the Scene Program with psychopomp-media (SCENE_PLANS.md, "Declare Narration And Sound"): media.say(id, &voice, text), media.dialogue, media.sfx, and audio.derive(Effect::pitch(..)), then media.finish()?. Each line is generated once and recorded in media.lock.json; later runs call nothing unless a declaration changed, and ElevenLabs words come from its character alignment with the script's spelling. Check the cost first with PSYCHOPOMP_MEDIA=plan cargo run -p <crate> (zero API calls), time with PSYCHOPOMP_MEDIA=draft, and clean up with PSYCHOPOMP_MEDIA=prune. Move a narrate.ts scene with cargo run -p psychopomp-media -- adopt scenes/<name>/narration (no regeneration). Done when a plain run reports every resource =.

  4. Author the Scene Program in scenes/<name> (add it to the workspace). Use psychopomp::score (SCENE_PLANS.md, "Author With The Score DSL") so PlanBuilder is the only mut binding and every actor (Stage, Camera, Caption, Callout, RollingNumber, Checklist, Meter, Bars, Subtitles, Confetti, Terminal, Chat, ChangedFiles, LowerThird, Lens) is an immutable value whose methods return composable Beats (.then, .also, .with, .on_end, .after, .early, stagger, each, at!(scene, time => ...)). Schedule clips with Narration::reading, build elements with StageElement::card|orb|beam|packet|label|ring and relative psychopomp::layout::Placement envelopes on StagePost::RESTRAINED, frame with Caption::header|chip|footer, and play sounds with sfx::*.beat(id, gain_db) (or audio.beat(gain_db) for psychopomp-media). Load the explainer-motion skill and apply it to every beat: cards settle_in, beams connect, messages send, replies wait for .reply(), impacts hit, the hero orb_in, the fix's rewind; use Callout to pin annotations to Stage elements or Editor code ranges and RollingNumber for live counters/timers; drive camera moves through stage.camera() (establish, frame, follow, release, orbit, whip, dolly_zoom). Reach for the visualization and text overlays instead of hand-building them from Stage labels and rings: Checklist for checks that run and resolve, Meter (MeterPlan::countdown) for a timeout ring, Bars for before/after numbers, Confetti for a success beat, and Subtitles (SubtitlesPlan::from_spoken) to burn in word-timed captions. Changes are Diffs of keep, add(step), and remove(step) lines, each step keyed to a phrase. Done when cargo run -p <crate> writes the reel and cargo run --release -- plan validate <reel> reports valid. A missing phrase panics with its clip: change the anchor to words the transcript actually contains.

  5. Review before rendering. Get segment spans from plan inspect <reel>, then contact-sheet each segment at its before, switch, after, and code beats:

    bun scripts/sheet.ts <reel> t1,t2,... --theme neutral --shutter --out output/sheet.jpg
    

    When tuning the look, set PSYCHOPOMP_SHADER_DIR=crates/psychopomp-render/src/render and edit stage.wgsl/stage_post.wgsl: every frame and sheet picks up shader edits without a Rust rebuild. Then render one behavior segment with audio (plan render <reel> out.mp4 --cue <scene-id>) and inspect frames extracted during motion. Done when every segment has been looked at and no text overlaps, clips, or reads against the wrong chip.

  6. Render and verify the whole reel:

    cargo run --release -- plan render <reel> output/<name>.mp4 --theme neutral
    

    Done when ffprobe shows 1920x1080, 60 fps, AAC audio, and a duration matching plan inspect, and loudness is near -16 LUFS with peaks under -1 dBFS.

  7. Deliver the MP4 path. Commit the scene, narration assets, and any engine changes in Psychopomp with conventional messages.

Improving Psychopomp

When a reel needs something the engine cannot do, add it to Psychopomp rather than working around it in one scene: plan types and validation in crates/psychopomp, strict-channel preflight in plan_runtime, pixels in render, GPU-free tests plus an #[ignore] GPU test, and the docs AGENTS.md asks you to keep current.

Build from small reusable pieces. Interpolation, easing, curves, shape ports, and connectors belong in psychopomp::math (organized like pmndrs math: core lerp/ remap/smoothstep, easing, curve, shapes, random; glam vectors). Extend it instead of inlining math in a renderer or scene, and split renderers into one small helper per element, as render/stage.rs does. Keep cargo fmt --check, cargo clippy --workspace --all-targets --all-features -- -D warnings, and cargo test --workspace green.

04 同仓库更多 Skills

mikker
mikker/dotfiles

unslop

Cut AI tells from any writing.

★ 116
mikker
mikker/dotfiles

stageshow

Build faux product UI that looks like a real product, as a still illustration or an animated demo with a cursor. Browser and app windows, dashboards, phones, notifications, terminals, bento grids and cursor walkthroughs, framed, masked and cropped the way a marketing page, feature card or docs hero needs them. Use whenever someone wants a fake or mocked UI, a product demo or walkthrough animation, a hero or feature-card illustration of an app, a product shot in the style of a polished marketing site, or an animated cursor doing things in an interface, even if they never say "faux UI". React and plain CSS.

前端开发
★ 116
mikker
mikker/dotfiles

clean-copy

Cut interface copy that shouldn't exist — captions that restate a label, hints that pre-empt a worry the user never had, warnings that are scar tissue from a fixed bug. Use when writing or reviewing any user-facing string (labels, hints, empty states, toasts, confirmations, button text), or when asked to clean up / tighten copy.

★ 116
mikker
mikker/dotfiles

elyx

Elyx is a design tool with local, AI-friendly `.elyx` files for screens, components, layouts, flows, and design systems. This skill is only available to agents running in external harnesses while using the Elyx CLI. It is unavailable and must not be used when running in the ACP harness inside the Elyx app. In external harnesses, use this skill before reading, reasoning about, or answering any question that touches Elyx or `.elyx` files — authoring, editing, validating, inspecting, reviewing, refactoring, comparing, or recommending changes, including read-only analysis where you produce no edit. Do not reason about `.elyx` from source text alone; imports, instances, overrides, and layout only resolve through the tools.

★ 116
mikker
mikker/dotfiles

uikit-app-modernization

Modernizes UIKit apps for multi-window environments by replacing legacy shared-state APIs with context-appropriate modern alternatives. This includes references to mainScreen, interfaceOrientation, application and scene lifecycle, as well as safe area inset updates.

★ 116
mikker
mikker/dotfiles

swiftui-whats-new-27

New SwiftUI APIs, behaviors, and deprecations in the 2027 OS releases (iOS 27 and aligned macOS/watchOS/tvOS/visionOS). Consult when asked what's new in SwiftUI 27, or when working with: - @State compile errors after an SDK update ("used before being initialized", "invalid redeclaration of synthesized property") or @State becaming a macro - @ViewBuilder/@ContentBuilder ambiguous overloads or type-check regressions; drag-to-reorder in any container (List, stacks, grids, custom layouts) via reorderable()/reorderContainer and its drag-and-drop - AsyncImage caching, reloading on scroll, or a custom URLSession - Swipe actions outside List (ScrollView, LazyVStack, LazyVGrid) via swipeActions()/swipeActionsContainer() - Toolbar overflow, visibility (visibilityPriority, ToolbarOverflowMenu, toolbarMinimizeBehavior), and pinning - Presenting a confirmationDialog or alert from an optional item binding

★ 116