oma-video — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited oma-video (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Generate finished .mp4 videos through a key-optional, 3-tier (CLI-first / MCP / guided) provider router while preserving deterministic asset buses (script -> timing -> render-spec), reproducible manifests, cost controls, and capture-path safety.
--mode shorts, 9:16)--mode explainer, 16:9 / 9:16)--mode demo --source file, 16:9)--mode demo --source web --url <url>) — a human drives the on-screen flow; the tool only opens a headed browser and records. Example categories are equal and illustrative only: demo, walkthrough, onboarding clip, bug repro, app-review screencast.render-spec.json--format json)oma-imageoma-slide (this skill calls it internally for explainer frames)oma-voice--source web); live streaming is out of scopedemo --source file: a screen-capture file path (--capture) or Cap availabilitydemo --source web: a target --url (any URL — local/staging/prod), optional --device/--ready-selector/--show-cursor/--polish/--capture-timeout; capture size is derived from --aspect/--device (no hardcoded size); a resolvable Playwright + an interactive TTY (else the run falls back to the guided protocol).agents/results/videos/<timestamp>-<shortid>-<mode>/script.json, timing.json, render-spec.jsonaudio/, visuals/, captions.srt / captions.vtt, the rendered <mode>-<slug>.mp4manifest.json with providers, asset hashes, cost breakdown, and exit codeoma video generate CLI + central error module (exit codes aligned with oma search fetch)resources/remotion/ (compositor)resources/vendor-matrix.md, resources/execution-protocol.md, resources/prompt-tips.md, config/video-config.yamldemo, confirm a capture path exists (or Cap is available); otherwise enter the guided protocol.config/video-config.yaml -> env vars -> CLI flags; check output path safety and limits.demo --source web has a --url, dispatch the headed web-capture path (human-driven flow, ENTER to stop); if Playwright is unresolvable OR there is no interactive TTY, fall back to the guided protocol (no hang).demo --source file has no capture and Cap is unavailable, emit the guided capture protocol and stop (exit code maps to capture-required).order; only chain exhaustion is a stage failure.oma video doctor; fall back to the MPT compositor where applicable.<mode>-<slug>.mp4 and manifest.json exist in the run directory; all schemas validate.| Action | SSL primitive | Evidence |
|---|---|---|
| Validate brief + mode | VALIDATE | Clarification protocol, mode inference |
| Select provider strategy | SELECT | Vendor matrix, providers.*.order, availability |
| Read brief / capture | READ | Brief text, --capture path |
| Generate script | CALL_TOOL | AgentScriptProvider -> script.json |
| Synthesize narration + timing | CALL_TOOL | oma-voice -> audio/*.wav + timing.json |
| Produce visuals | CALL_TOOL | oma-image / oma-slide / stock -> visuals/* |
| Build captions | WRITE | key-free captions.srt / .vtt from timing |
| Compose render-spec | WRITE | render-spec.json (determinism boundary) |
| Render video | CALL_TOOL | Remotion / MPT compositor -> <mode>-<slug>.mp4 |
| Validate result | VALIDATE | Schema parse, manifest hashes, exit code |
| Report output | NOTIFY | Run-dir + mp4 path summary |
oma video generate, oma video doctor, oma video list-providers, oma video renderresources/remotion/), prompt tips, vendor matrix, video configoma video doctor
oma video generate "<brief>" --mode shorts --aspect auto --captions tiktok --format jsonExplainer from a README, with a deterministic seed:
oma video generate "explain this project" --mode explainer --aspect 16:9 --seed 42 --out ./outDemo from a screen capture:
oma video generate "feature walkthrough" --mode demo --capture <absolute-path>.mp4Deterministic re-render from an existing run:
oma video render .agents/results/videos/20260603-143052-ab12cd-shorts| Scope | Resource target |
|---|---|
LOCAL_FS | Briefs, captures, assets, render-spec, run dir, manifests |
PROCESS | oma-image / oma-slide CLIs, Remotion / MPT, Cap CLI, Playwright web-capture driver (subprocess) |
NETWORK | Voicebox MCP (localhost), oma-image vendor APIs, the user-supplied --url for web capture (masked in logs/manifest), optional Pexels / Pixelle / RunningHub |
CREDENTIALS | oma-image vendor auth, optional PEXELS_API_KEY / RUNNINGHUB_API_KEY. Web capture handles NO credentials — a human logs in if the flow needs it; nothing is stored or printed. |
$PWD (or --allow-external-out is set).demo --source file: the capture path exists, is absolute/$PWD-guarded, and is a valid format.demo --source web: a --url is supplied (else SchemaValidationError); a resolvable Playwright + an interactive TTY exist (else the run falls back to the guided protocol).Clarification Protocol below.cost.guardrail_usd ($0.20, configurable) or --max-usd. --yes / OMA_VIDEO_YES=1 bypass. Local/free paths carry zero cost.$PWD require --allow-external-out. --capture is absolutized, $PWD-guarded, and format-validated; external assets are copied into the run dir and hashed (no URL refs).render-spec.json + asset files (+ seed + embedded Pretendard font) are the determinism boundary. Re-rendering the same render-spec is byte-stable; OMA_VIDEO_MOCK=1 replays golden fixtures.limits.max_duration_sec = 180, limits.max_scenes = 40 (wall-time + memory bound).--max-usd.--source file the skill guides but does not screen-record autonomously; for --source web the tool only opens a headed browser and records while the human drives the entire on-screen flow (interactive ENTER to stop). The mechanism prescribes nothing about what the flow is or what the recording is for.--url and any query tokens are masked in logs and in manifest.json; credentials are never stored or printed. Recording and all outputs are confined to the run dir. On-screen sensitive input is captured as-is — the user controls the flow. Multi-page navigation (popup / new tab / redirect) is recorded generically, with no assumption about the flow's shape.-y / no stdin) — the run falls back to guided and never hangs. Live capture is outside the determinism boundary, so the manifest records nondeterministic: true.Before invoking oma video generate, the calling agent runs this checklist. If any answer is "no / unknown", clarify or infer-and-confirm with the user first.
Required signal (must be present or inferable):
demo --source web — a --url)--source file (a --capture path) or --source web (a --url)? For --source web, state up front that a human drives the on-screen flow and that the tool never automates any login.Strongly recommended (ask if absent AND not inferable):
9:16 (shorts/reels), 16:9 (explainer/demo), 1:1, or auto (snaps to the mode default).tiktok (centered, animated), lower-third, or none.auto (derived from the script).none; music upbeat / calm / none.Amplification shortcut. For a one-line brief (e.g. "shorts about Jeju coffee"), do not pop a questionnaire if the request is genuinely simple. Instead amplify inline and show the user the inferred plan before invoking:
User: "make a short about Jeju coffee" Agent: "I'll generate this as: mode `shorts`, 9:16, ~30s, oma-image stills with Ken Burns, TikTok captions, locale `en`, calm music. Proceed, or adjust mode/aspect/voice?"
Skip clarification when the user authored a full brief (mode + topic + aspect + captions). Respect their flags verbatim.
Output language. Narration and on-screen text are authored in the requested locale. Image-generation prompts passed to oma-image are sent in English (image models are trained predominantly on English captions); translate the user's request and show the translated version during amplification.
| Mode | Aspect | Source | Default visual | Compositor | Output |
|---|---|---|---|---|---|
shorts | 9:16 | synthetic (topic) | oma-image stills + Ken Burns; Pexels (key) · Pixelle AIGC (key) opt | Remotion · MPT alt | shorts-<slug>.mp4 |
explainer | 16:9 / 9:16 | README · code · data | oma-slide frames + oma-image diagrams + code | Remotion (deterministic) | explainer-<slug>.mp4 |
demo | 16:9 | --source file (Cap / capture file) · --source web (headed browser at --url) | raw footage (default) · Remotion intro · zoom · callouts (--polish) | Remotion polish | demo-<slug>.mp4 |
| Tier | Surface | Providers | Trigger |
|---|---|---|---|
| 1 | CLI-first (subprocess, deterministic) | Remotion render, MPT, oma-image, oma-slide, oma-voice | always available (key-free defaults) |
| 2 | MCP | Voicebox MCP (voice/timing), Pixelle-MCP (AIGC, off by default) | MCP server reachable; Pixelle needs explicit consent + key |
| 3 | Guided (human-in-the-loop) | Playwright headed web capture (--source web, human drives the flow), Cap (capture), openscreen fallback | demo mode; web capture needs a resolvable Playwright + a TTY (else guided protocol) |
#### Standalone
/oma-video make a 30s short about Jeju coffee
/oma-video --mode explainer --aspect 16:9 explain this project from the README
/oma-video --mode demo --source file --capture ~/recordings/walkthrough.mp4 feature demo
/oma-video --mode demo --source web --url http://localhost:3000 record my app flow
/oma-video --mode demo --source web --url <url> --ready-selector "#app" --polish onboarding clip#### Shell CLI
oma video generate "<brief>" [--mode shorts|explainer|demo] \
[--aspect 9:16|16:9|1:1|auto] [--locale <lang>] \
[--captions tiktok|lower-third|none] \
[--visual auto|generate|stock|aigc|slide] \
[--voice <profile>|none] [--music upbeat|calm|none] \
[--duration <sec>|auto] [--compositor remotion|mpt] \
[--capture <path>] \
[--source file|web] [--url <url>] [--device <name>] \
[--ready-selector <css>] [--show-cursor] [--polish] \
[--capture-timeout <sec>] [--capture-stop duration:<sec>|selector:<css>] \
[--out <dir>] [--allow-external-out] \
[--max-usd <n>] [--seed <n>] [--timeout 600] [-y] \
[--dry-run] [--format text|json] [--no-brief-in-manifest]
# --source web: headed browser at --url; capture size derived from --aspect/--device (no hardcoded size).
# A human drives the on-screen flow; press ENTER to stop. NO credential automation. --url/tokens masked.
# Non-interactive (CI / -y / no TTY) or unresolvable Playwright -> falls back to the guided protocol (no hang).
# --capture-stop gives CI a non-interactive stop (duration / selector) in place of the ENTER prompt.
oma video doctor # Node/Chromium/FFmpeg · Voicebox MCP · oma-image vendors · Pixelle-MCP · Cap · Playwright (web capture)
oma video doctor --install-playwright # one-time: npm i playwright + chromium (web capture)
oma video list-providers # availability + key/fallback status
oma video render <runDir> # re-render from render-spec.json (deterministic)#### Shared Infrastructure (from other skills) Other skills call oma video generate --format json and parse the JSON envelope ({exitCode, runDir, manifestPath, outputs}) from stdout. The deterministic boundary is render-spec.json + assets, so a downstream consumer can re-render via oma video render <runDir> without re-running script/voice/visual generation.
.agents/results/videos/
└── 20260603-143052-ab12cd-shorts/ # {timestamp}-{shortid}-{mode}
├── script.json # determinism boundary start
├── timing.json
├── render-spec.json # deterministic compute boundary
├── audio/
│ └── narration-01.wav …
├── visuals/
│ └── scene-01.jpg …
├── captions.srt
├── captions.vtt
├── shorts-<slug>.mp4
└── manifest.json # reproducibility recordFollow resources/execution-protocol.md step by step. See resources/vendor-matrix.md for provider precheck + fallback-chain rules. Use resources/prompt-tips.md for writing effective briefs per mode. Before submitting, run resources/checklist.md. The vendored Remotion compositor lives at resources/remotion/ (see its README.md). The web-capture driver lives at resources/playwright/record.mjs (runs as a subprocess under the resolved Playwright; never imported into the CLI). The MPT fallback compositor driver lives at resources/mpt/driver.py (consumed by the CLI's mpt-project internals).
Project-specific settings: config/video-config.yaml. Env vars: OMA_VIDEO_DEFAULT_MODE, OMA_VIDEO_DEFAULT_OUT, OMA_VIDEO_YES, PEXELS_API_KEY, RUNNINGHUB_API_KEY (+ POLLINATIONS_API_KEY via oma-image), OMA_VIDEO_MOCK, OMA_VIDEO_PLAYWRIGHT_DIR (web-capture Playwright override), OMA_VIDEO_PWTEST (opt-in web-capture e2e).
resources/execution-protocol.mdresources/vendor-matrix.mdresources/prompt-tips.mdresources/checklist.mdresources/remotion/README.md../_shared/core/context-loading.md~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.