Blogify workflow
Produce four reviewable artifacts from the recording: transcript, takeaways,
selected frames, and final prose. Run the audio and frame tracks in parallel when
the input is video.
Requirements
$OMLX_BASE_URL should point at the OpenAI-compatible media endpoint (defaults
to http://127.0.0.1:8000 if unset); set $OMLX_API_KEY only if the
endpoint requires auth (otherwise an empty key is assumed).
uv (runs the bundled Python scripts and auto-installs declared
dependencies), ffmpeg, ffprobe, and ImageMagick (magick/convert) must
be available.
- Keep all inputs and outputs in the user's workspace. Pass absolute paths; the
scripts refuse to write inside the skill directory.
First: get the intent
Collect the output type, audience, tone, and scope from the prompt or user
before drafting. Use references/authoring.md for the authoring checklist.
Workflow
- Transcribe. Run `uv run scripts/transcribe.py --input --output-dir
- Mine takeaways. From the transcript, synthesize per-topic takeaways in
the reader's voice. Correct mistranscribed jargon against ground truth
(slides, repo names). Stay grounded — never invent claims. For long
recordings, fan out per-topic synthesis to sub-agents.
- Sample frames (in parallel with 1–2).
uv run scripts/sample_frames.py --input <video> --output-dir <sampled-frames-dir> grabs scene-change + periodic
frames named by timestamp. Then run uv run scripts/dedupe_frames.py --frames-dir <sampled-frames-dir> --output-dir <dedup-frames-dir> to drop
near-duplicates.
- Classify frames.
uv run scripts/classify_frames.py --frames-dir <dedup> --output <dir>/manifest.json --context "<one line about the video>" --categories "<A,B,...,OTHER>" --batch-size 4 --select-dir <selected-dir>. Use a SHORT enum of categories —
the vision model is a reliable classifier, a poor open-ended captioner. It
returns constrained JSON labels (validated against the enum). --batch-size
classifies several frames per request to amortize the endpoint's large fixed
per-request cost (~6–8 s); 4 is a safe default, raise it for distinct frames.
For sampling pitfalls, batching, and targeted re-sampling, use references/frames.md. The local OMLX
model is the default; if its per-request cost makes a large frame set
impractical even when batched, references/frames.md documents a privacy-gated cloud-subagent
fallback (only with explicit user consent, since frames leave the machine).
- Pick + polish images. For chosen frames, re-extract at full resolution
with `uv run scripts/extract_frame.py --input --second --output
- Author the output. Draft the doc/blog per the requested intent. Add a
screenshot only where it makes the text easier to understand, placed next to
the concept, with descriptive alt text. Use
references/authoring.md.
- If in a repo, wire and validate. Follow the repo's image/LFS conventions,
optionally embed the recording/slides, run its markdown lint / link / TOC
checks, and respect its PR conventions (some repos want changes left in the
working tree). Use
references/authoring.md.
Notes
- Keep the transcript, takeaways, frame manifest, and selected frames in the
workspace — deliver the artifacts, not just the final prose.
- The transcript and the frame filenames share the video timeline, so you can
line up "demoed at 34:59" with the frame captured at 34:59.
- Run only the scripts bundled here; do not copy them elsewhere.
1---2name: blogify3description: Use this skill to turn a video or audio recording (a talk, meeting, or demo) into written content: documentation, a blog post, tutorial, changelog, or notes. Handles transcription, takeaway synthesis, screenshot/frame selection, and grounded drafting from local OpenAI-compatible media models. Not for real-time transcription, generic video editing, or non-generative media processing.4---56# Blogify workflow78Produce four reviewable artifacts from the recording: transcript, takeaways,9selected frames, and final prose. Run the audio and frame tracks in parallel when10the input is video.1112## Requirements1314- `$OMLX_BASE_URL` should point at the OpenAI-compatible media endpoint (defaults15 to `http://127.0.0.1:8000` if unset); set `$OMLX_API_KEY` only if the16 endpoint requires auth (otherwise an empty key is assumed).17- `uv` (runs the bundled Python scripts and auto-installs declared18 dependencies), `ffmpeg`, `ffprobe`, and ImageMagick (`magick`/`convert`) must19 be available.20- Keep all inputs and outputs in the user's workspace. Pass absolute paths; the21 scripts refuse to write inside the skill directory.2223## First: get the intent2425Collect the **output type, audience, tone, and scope** from the prompt or user26before drafting. Use `references/authoring.md` for the authoring checklist.2728## Workflow29301. **Transcribe.** Run `uv run scripts/transcribe.py --input <file> --output-dir31 <dir>`. Produces `transcript.md` (timestamped) and `chunks.json`. The model is32 auto-discovered (prefers parakeet); override with `--model`. For tuning and33 limitations, use `references/transcription.md` (no timestamps, no diarization34 — reconstruct/attribute accordingly).352. **Mine takeaways.** From the transcript, synthesize per-topic takeaways in36 the reader's voice. Correct mistranscribed jargon against ground truth37 (slides, repo names). Stay grounded — never invent claims. For long38 recordings, fan out per-topic synthesis to sub-agents.393. **Sample frames** (in parallel with 1–2). `uv run scripts/sample_frames.py --input40 <video> --output-dir <sampled-frames-dir>` grabs scene-change + periodic41 frames named by timestamp. Then run `uv run scripts/dedupe_frames.py --frames-dir42 <sampled-frames-dir> --output-dir <dedup-frames-dir>` to drop43 near-duplicates.444. **Classify frames.** `uv run scripts/classify_frames.py --frames-dir <dedup>45 --output <dir>/manifest.json --context "<one line about the video>"46 --categories "<A,B,...,OTHER>" --batch-size 4 --select-dir <selected-dir>`. Use a SHORT enum of categories —47 the vision model is a reliable *classifier*, a poor open-ended captioner. It48 returns constrained JSON labels (validated against the enum). `--batch-size`49 classifies several frames per request to amortize the endpoint's large fixed50 per-request cost (~6–8 s); 4 is a safe default, raise it for distinct frames.51 For sampling pitfalls, batching, and targeted re-sampling, use `references/frames.md`. The local OMLX52 model is the default; if its per-request cost makes a large frame set53 impractical even when batched, `references/frames.md` documents a **privacy-gated cloud-subagent54 fallback** (only with explicit user consent, since frames leave the machine).555. **Pick + polish images.** For chosen frames, re-extract at full resolution56 with `uv run scripts/extract_frame.py --input <video> --second <secs> --output57 <dir>/shot.png` and crop overlays with `uv run scripts/crop_frames.py`. Verify picks58 visually before using them.596. **Author the output.** Draft the doc/blog per the requested intent. Add a60 screenshot only where it makes the text easier to understand, placed next to61 the concept, with descriptive alt text. Use `references/authoring.md`.627. **If in a repo, wire and validate.** Follow the repo's image/LFS conventions,63 optionally embed the recording/slides, run its markdown lint / link / TOC64 checks, and respect its PR conventions (some repos want changes left in the65 working tree). Use `references/authoring.md`.6667## Notes6869- Keep the transcript, takeaways, frame manifest, and selected frames in the70 workspace — deliver the artifacts, not just the final prose.71- The transcript and the frame filenames share the video timeline, so you can72 line up "demoed at 34:59" with the frame captured at 34:59.73- Run only the scripts bundled here; do not copy them elsewhere.