[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6BYX30D2C62F2RTMRA6M0R6":3,"skill-same:01M6BYX30D2C62F2RTMRA6M0R6":195},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":6,"ownerHtmlUrl":52,"ownerBlogUrl":6,"ownerDescription":53,"updatedAt":54,"install":55,"resources":68},"01M6BYX30D2C62F2RTMRA6M0R6","oma-video",null,"Short-form, explainer, and demo video generation via a key-optional 3-tier router. Composes scripts, oma-voice narration, oma-image\u002Foma-slide\u002Fstock visuals, key-free captions, and a vendored Remotion compositor into reproducible run directories. Routes three modes — shorts\u002Freels (9:16), explainer (16:9 README\u002Fcode\u002Fdata), and demo\u002Fwalkthrough (screen capture, incl. supervised headed web-app capture of any URL). Use for video, shorts, reels, short-form, demo, explainer, walkthrough, screencast, web capture, video generation, 영상, 숏폼, 쇼츠, 릴스, 데모, 설명 영상.","mrmarbury\u002FPalmSync4Mac","mrmarbury","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F114311?v=4","01M6BYSN920J8AMQ0W6HGSBH60","Stefan Marbury","01M6BYSNDEACDBNBPNRNCVYAPJ",2,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"Video","oma video","visuals","demo video","run","code","demo","Reproducible","data","image","Remotion","Captions","walkthrough","explainer","voice","screen capture","video generation","web","2026-11-10 10:12:30",false,"---\nname: oma-video\ndescription: Short-form, explainer, and demo video generation via a key-optional 3-tier router. Composes scripts, oma-voice narration, oma-image\u002Foma-slide\u002Fstock visuals, key-free captions, and a vendored Remotion compositor into reproducible run directories. Routes three modes — shorts\u002Freels (9:16), explainer (16:9 README\u002Fcode\u002Fdata), and demo\u002Fwalkthrough (screen capture, incl. supervised headed web-app capture of any URL). Use for video, shorts, reels, short-form, demo, explainer, walkthrough, screencast, web capture, video generation, 영상, 숏폼, 쇼츠, 릴스, 데모, 설명 영상.\n---\n\n# Video Agent - Short-form, Explainer & Demo Router\n\n## Scheduling\n\n### Goal\nGenerate finished `.mp4` videos through a key-optional, 3-tier (CLI-first \u002F MCP \u002F guided) provider router while preserving deterministic asset buses (script -> timing -> render-spec), reproducible manifests, cost controls, and capture-path safety.\n\n### Intent signature\n- User asks for a short-form video, shorts\u002Freels clip, TikTok\u002FYouTube Short, explainer, demo, walkthrough, or screencast.\n- User wants a topic, README, code, or data turned into a narrated, captioned video.\n- Another skill needs shared video-generation infrastructure (script -> assets -> render).\n\n### When to use\n\n- Generating short-form video (shorts \u002F reels) from a topic or brief (`--mode shorts`, 9:16)\n- Generating an explainer from a README, code, or data set (`--mode explainer`, 16:9 \u002F 9:16)\n- Producing a demo \u002F walkthrough from a screen capture file (`--mode demo --source file`, 16:9)\n- Supervised headed web-app capture of any URL (`--mode demo --source web --url \u003Curl>`) — 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.\n- Re-rendering an existing run deterministically from `render-spec.json`\n- Other skills needing video-generation infrastructure (shared invocation via `--format json`)\n\n### When NOT to use\n\n- Generating a single still image -> use `oma-image`\n- Generating a slide deck \u002F presentation -> use `oma-slide` (this skill calls it internally for explainer frames)\n- Generating speech audio only (no video) -> use `oma-voice`\n- Non-linear video editing of an existing finished mp4 -> out of scope (OpenCut-MCP deferred)\n- Supervised headed web capture is in-scope (`--source web`); live streaming is out of scope\n- Interactive HTML explainer document (not a video) -> use `oma-explainer`\n\n### Expected inputs\n- A brief (topic \u002F README path \u002F data) plus optional mode, aspect, locale, captions, visual, voice, music, duration, compositor, capture path, seed\n- For `demo` `--source file`: a screen-capture file path (`--capture`) or Cap availability\n- For `demo` `--source web`: a target `--url` (any URL — local\u002Fstaging\u002Fprod), optional `--device`\u002F`--ready-selector`\u002F`--show-cursor`\u002F`--polish`\u002F`--capture-timeout`; capture size is derived from `--aspect`\u002F`--device` (no hardcoded size); a resolvable Playwright + an interactive TTY (else the run falls back to the guided protocol)\n- Authentication\u002Fenvironment state for oma-voice (Voicebox MCP), oma-image vendors, and optional Pexels \u002F Pixelle keys\n\n### Expected outputs\n- A run directory under `.agents\u002Fresults\u002Fvideos\u002F\u003Ctimestamp>-\u003Cshortid>-\u003Cmode>\u002F`\n- Deterministic asset bus: `script.json`, `timing.json`, `render-spec.json`\n- `audio\u002F`, `visuals\u002F`, `captions.srt` \u002F `captions.vtt`, the rendered `\u003Cmode>-\u003Cslug>.mp4`\n- `manifest.json` with providers, asset hashes, cost breakdown, and exit code\n\n```yaml\noutputs:\n  - name: video\n    description: rendered \u003Cmode>-\u003Cslug>.mp4 in the run directory\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002F*.mp4\"\n    required: true\n  - name: manifest\n    description: reproducibility record (providers, asset sha256 hashes, cost breakdown, exit code)\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002Fmanifest.json\"\n    required: true\n  - name: render-spec\n    description: deterministic compute boundary consumed by `oma video render \u003CrunDir>`\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002Frender-spec.json\"\n    required: true\n  - name: captions\n    description: key-free caption tracks aligned to timing.json\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002Fcaptions.srt\"\n    required: false\n```\n\n### Dependencies\n- `oma video generate` CLI + central error module (exit codes aligned with `oma search fetch`)\n- oma-voice (Voicebox MCP), oma-image, oma-slide as key-free fallback providers\n- Vendored Remotion project at `resources\u002Fremotion\u002F` (compositor)\n- `resources\u002Fvendor-matrix.md`, `resources\u002Fexecution-protocol.md`, `resources\u002Fprompt-tips.md`, `config\u002Fvideo-config.yaml`\n\n### Control-flow features\n- Branches by mode (shorts \u002F explainer \u002F demo), aspect, visual strategy, provider availability, cost threshold, capture requirement, and path safety\n- Runs a per-capability fallback chain (real key\u002Fresource -> key-free fallback) per backend rule 11\n- Reads briefs\u002Fcaptures and writes assets, render-spec, and manifests\n- Calls external resources: Voicebox MCP, oma-image vendors, Remotion toolchain, optional Pexels \u002F Pixelle\n\n## Structural Flow\n\n### Entry\n1. Validate that the brief carries enough mode\u002Ftopic signal (or infer the mode from keywords).\n2. For `demo`, confirm a capture path exists (or Cap is available); otherwise enter the guided protocol.\n3. Resolve defaults from `config\u002Fvideo-config.yaml` -> env vars -> CLI flags; check output path safety and limits.\n\n### Scenes\n1. **PREPARE**: Resolve mode\u002Faspect\u002Flocale, clarify or amplify the brief, choose the visual + compositor strategy.\n2. **ACQUIRE**: Probe provider availability (voice \u002F visual \u002F caption \u002F compositor), validate capture path, check cost.\n3. **ACT**: Run the mode pipeline — script -> (voice ∥ visuals ∥ captions) -> render-spec -> compositor render.\n4. **VERIFY**: Validate every asset-bus schema, manifest hashes, exit code, and the output mp4.\n5. **FINALIZE**: Return the run-dir path, the mp4 path, and any provider\u002Fcoverage warnings.\n\n### Transitions\n- If the brief lacks a clear mode, infer from keywords (shorts\u002Freels -> shorts; README\u002Fcode -> explainer; capture -> demo) and show the user the inferred plan before generating.\n- If the selected visual provider key is absent (Pexels \u002F Pixelle), fall through the chain to the key-free oma-image stills + Ken Burns fallback and annotate coverage.\n- If `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).\n- If `demo` `--source file` has no capture and Cap is unavailable, emit the guided capture protocol and stop (exit code maps to capture-required).\n- If estimated cost (Pixelle \u002F RunningHub credits) exceeds the guardrail, require confirmation unless bypassed.\n\n### Failure and recovery\n- If a provider is unavailable, try the next provider in the capability's `order`; only chain exhaustion is a stage failure.\n- If the Remotion toolchain is not bootstrapped, point the user to `oma video doctor --install` (one-time: deps + headless shell + Pretendard font); fall back to the MPT compositor where applicable (MPT itself needs a one-time `oma video doctor --install-mpt`).\n- If Voicebox MCP is down, fall back to estimated timing (still produces captions). A whisper.cpp hop between the two is reserved but not yet wired (`TODO(oma-deferred): whisper-cpp`).\n- If the brief locale is non-source, translate via oma-translator (key-free); if absent, warn and keep source text.\n\n### Exit\n- Success: `\u003Cmode>-\u003Cslug>.mp4` and `manifest.json` exist in the run directory; all schemas validate.\n- Partial success: video renders with a key-free fallback in place of a paid provider; coverage is annotated in warnings.\n- Failure: no video is produced and the route\u002Fcost\u002Fcapture\u002Fauth\u002Fsafety blocker is explicit in the exit code + manifest.\n\n## Logical Operations\n\n### Actions\n| Action | SSL primitive | Evidence |\n|--------|---------------|----------|\n| Validate brief + mode | `VALIDATE` | Clarification protocol, mode inference |\n| Select provider strategy | `SELECT` | Vendor matrix, `providers.*.order`, availability |\n| Read brief \u002F capture | `READ` | Brief text, `--capture` path |\n| Generate script | `CALL_TOOL` | AgentScriptProvider -> `script.json` |\n| Synthesize narration + timing | `CALL_TOOL` | oma-voice -> `audio\u002F*.wav` + `timing.json` |\n| Produce visuals | `CALL_TOOL` | oma-image \u002F oma-slide \u002F stock -> `visuals\u002F*` |\n| Build captions | `WRITE` | key-free `captions.srt` \u002F `.vtt` from timing |\n| Compose render-spec | `WRITE` | `render-spec.json` (determinism boundary) |\n| Render video | `CALL_TOOL` | Remotion \u002F MPT compositor -> `\u003Cmode>-\u003Cslug>.mp4` |\n| Validate result | `VALIDATE` | Schema parse, manifest hashes, exit code |\n| Report output | `NOTIFY` | Run-dir + mp4 path summary |\n\n### Tools and instruments\n- `oma video generate`, `oma video doctor`, `oma video list-providers`, `oma video render`\n- Provider adapters: AgentScript, oma-voice, oma-image, oma-slide, Pexels, Pixelle, oma-captions, Cap, Remotion, MPT\n- Vendored Remotion project (`resources\u002Fremotion\u002F`), prompt tips, vendor matrix, video config\n\n### Canonical command path\n```bash\noma video doctor\noma video generate \"\u003Cbrief>\" --mode shorts --aspect auto --captions tiktok --format json\n```\n\nExplainer from a README, with a deterministic seed:\n```bash\noma video generate \"explain this project\" --mode explainer --aspect 16:9 --seed 42 --out .\u002Fout\n```\n\nDemo from a screen capture:\n```bash\noma video generate \"feature walkthrough\" --mode demo --capture \u003Cabsolute-path>.mp4\n```\n\nDeterministic re-render from an existing run:\n```bash\noma video render .agents\u002Fresults\u002Fvideos\u002F20260603-143052-ab12cd-shorts\n```\n\n### Resource scope\n| Scope | Resource target |\n|-------|-----------------|\n| `LOCAL_FS` | Briefs, captures, assets, render-spec, run dir, manifests |\n| `PROCESS` | oma-image \u002F oma-slide CLIs, Remotion \u002F MPT, Cap CLI, Playwright web-capture driver (subprocess) |\n| `NETWORK` | Voicebox MCP (localhost), oma-image vendor APIs, the user-supplied `--url` for web capture (masked in logs\u002Fmanifest), optional Pexels \u002F Pixelle \u002F RunningHub |\n| `CREDENTIALS` | oma-image vendor auth, optional `PEXELS_API_KEY` \u002F `RUNNINGHUB_API_KEY`. Web capture handles NO credentials — a human logs in if the flow needs it; nothing is stored or printed. |\n\n### Preconditions\n- Brief carries enough signal for the mode, or the user approves the inferred\u002Famplified plan.\n- Output path is inside `$PWD` (or `--allow-external-out` is set).\n- For `demo` `--source file`: the capture path exists, is absolute\u002F$PWD-guarded, and is a valid format.\n- For `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).\n- Required provider availability holds for the chosen (non-fallback) path, or the fallback is acceptable.\n\n### Effects and side effects\n- Creates a run directory with assets, render-spec, captions, mp4, and manifest.\n- oma-voice plays narration on the speakers as a side effect of synthesis.\n- May call paid or rate-limited providers (Pexels \u002F Pixelle \u002F RunningHub) only when keys are present.\n\n### Guardrails\n\n1. **Clarify or infer before invoking**: if the mode\u002Ftopic is ambiguous, infer the mode from keywords and show the user the plan, or ask. Do NOT silently render from a vague brief. See `Clarification Protocol` below.\n2. **Key-optional dispatch (backend rule 11)**: every external capability has a real (key\u002Fresource) path AND a key-free fallback. Paid providers (Pexels, Pixelle) auto-enable only when their env key is present; otherwise the chain falls through to oma-image stills + Ken Burns. Default providers (oma-voice local, oma-image, oma-slide, Remotion) are key-free, so auto-triggering on keywords is safe.\n3. **Cost guardrail**: confirm before runs whose estimated cost is >= `cost.guardrail_usd` (`$0.20`, configurable) or `--max-usd`. `--yes` \u002F `OMA_VIDEO_YES=1` bypass. Local\u002Ffree paths carry zero cost.\n4. **Path safety**: output paths outside `$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).\n5. **Cancellable**: SIGINT\u002FSIGTERM aborts in-flight provider calls, the render, and the orchestrator.\n6. **Deterministic outputs**: `render-spec.json` + asset files (+ seed + embedded Pretendard font) are the determinism boundary. `oma video doctor --install` fetches the Pretendard woff2 once; if offline, the render gracefully falls back to system fonts, and byte-identical output across machines is only guaranteed once the font is present. Re-rendering the same render-spec is byte-stable; `OMA_VIDEO_MOCK=1` replays golden fixtures.\n7. **Limits**: `limits.max_duration_sec` = 180, `limits.max_scenes` = 40 (wall-time + memory bound).\n8. **Community-MCP consent**: Pixelle-MCP is off by default and requires one-time explicit consent + source review before connecting; RunningHub credits gate on `--max-usd`.\n9. **Demo is human-in-the-loop**: capture is performed by a human. For `--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.\n10. **Web-capture security**: NO credential automation of any kind — if a flow needs a login, a human performs it. The driver runs as a subprocess under the resolved Playwright (never imported into the CLI). The `--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 \u002F new tab \u002F redirect) is recorded generically, with no assumption about the flow's shape.\n11. **Web capture is key-optional + non-blocking**: web capture is the real branch; the guided protocol is the fallback when Playwright is unresolvable OR there is no interactive TTY (CI \u002F `-y` \u002F no stdin) — the run falls back to guided and never hangs. Live capture is outside the determinism boundary, so the manifest records `nondeterministic: true`.\n12. **Headed capture needs a display**: web capture launches a **headed** Chromium so the human can drive the flow. On display-less hosts (CI \u002F Linux without X), pass `--capture-stop duration:\u003Csec>|selector:\u003Ccss>` — the driver then runs headless (`resources\u002Fplaywright\u002Frecord.mjs --headless 1`) — or expect a capture error \u002F guided fallback.\n13. **Run-dir retention**: `.agents\u002Fresults\u002Fvideos\u002F\u003Crun>\u002F` accumulates one directory per run (assets + mp4 + manifest) and is **never auto-pruned**; the user deletes old run directories manually.\n14. **Exit codes align with `oma search fetch`** (0 ok, 1 generic, 2 safety, 3 not-found, 4 invalid-input, 5 auth-required, 6 timeout).\n\n### Clarification Protocol\n\nBefore invoking `oma video generate`, the calling agent runs this checklist. **If any answer is \"no \u002F unknown\", clarify or infer-and-confirm with the user first.**\n\n**Required signal (must be present or inferable):**\n- [ ] **Mode**: shorts \u002F explainer \u002F demo? Infer from keywords (shorts\u002Freels\u002F쇼츠\u002F릴스 -> shorts; README\u002Fcode\u002Fdata\u002Fexplain\u002F설명 -> explainer; demo\u002Fwalkthrough\u002Fcapture\u002F데모 -> demo).\n- [ ] **Topic \u002F source**: what is the video about? (a topic, a README\u002Fcode path, a capture file, or — for `demo` `--source web` — a `--url`)\n- [ ] **For `demo`**: `--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**.\n\n**Strongly recommended (ask if absent AND not inferable):**\n- [ ] **Aspect**: `9:16` (shorts\u002Freels), `16:9` (explainer\u002Fdemo), `1:1`, or `auto` (snaps to the mode default).\n- [ ] **Locale**: narration + caption language (default from config; translated via oma-translator when non-source).\n- [ ] **Captions**: `tiktok` (centered, static windowed cues), `lower-third`, or `none`.\n- [ ] **Duration**: target seconds (\u003C= 180) or `auto` (derived from the script).\n- [ ] **Voice \u002F music**: voice profile or `none`; music `upbeat` \u002F `calm` \u002F `none`. **The default voice is `none` → a silent video with estimated caption timing.** Pass `--voice \u003Cprofile>` (a Voicebox profile) whenever narration is expected. Music is rendered offline by Strudel and mixed at −18 dB; it needs a one-time `oma video doctor --install-strudel` and degrades to no music without it.\n\n**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:\n\n> User: \"make a short about Jeju coffee\"\n> 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\u002Faspect\u002Fvoice?\"\n\nSkip clarification when the user authored a full brief (mode + topic + aspect + captions). Respect their flags verbatim.\n\n**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.\n\n### Modes\n\n| Mode | Aspect | Source | Default visual | Compositor | Output |\n|------|:---:|--------|----------------|------------|--------|\n| `shorts` | 9:16 | synthetic (topic) | oma-image stills + Ken Burns; Pexels (key) · Pixelle AIGC (key) opt | Remotion · MPT alt | `shorts-\u003Cslug>.mp4` |\n| `explainer` | 16:9 \u002F 9:16 | README · code · data | oma-slide frames + oma-image diagrams + code | Remotion (deterministic) | `explainer-\u003Cslug>.mp4` |\n| `demo` | 16:9 | `--source file` (Cap \u002F capture file) · `--source web` (headed browser at `--url`) | raw footage (default) · Remotion intro · zoom · callouts (`--polish`) | Remotion polish | `demo-\u003Cslug>.mp4` |\n\n### 3-Tier Integration\n\n| Tier | Surface | Providers | Trigger |\n|:---:|---------|-----------|---------|\n| 1 | CLI-first (subprocess, deterministic) | Remotion render, MPT, oma-image, oma-slide, oma-voice | always available (key-free defaults) |\n| 2 | MCP | Voicebox MCP (voice\u002Ftiming), Pixelle-MCP (AIGC, off by default) | MCP server reachable; Pixelle needs explicit consent + key |\n| 3 | Guided (human-in-the-loop) | Playwright headed web capture (`--source web`, human drives the flow), Cap (capture), guided protocol fallback | `demo` mode; web capture needs a resolvable Playwright + a TTY (else guided protocol) |\n\n### Invocation\n\n#### Standalone\n```\n\u002Foma-video make a 30s short about Jeju coffee\n\u002Foma-video --mode explainer --aspect 16:9 explain this project from the README\n\u002Foma-video --mode demo --source file --capture ~\u002Frecordings\u002Fwalkthrough.mp4 feature demo\n\u002Foma-video --mode demo --source web --url http:\u002F\u002Flocalhost:3000 record my app flow\n\u002Foma-video --mode demo --source web --url \u003Curl> --ready-selector \"#app\" --polish onboarding clip\n```\n\n#### Shell CLI\n```\noma video generate \"\u003Cbrief>\" [--mode shorts|explainer|demo] \\\n                             [--aspect 9:16|16:9|1:1|auto] [--locale \u003Clang>] \\\n                             [--captions tiktok|lower-third|none] \\\n                             [--visual auto|generate|stock|aigc|slide] \\\n                             [--voice \u003Cprofile>|none] [--music upbeat|calm|cinematic|lofi|piano|none] \\\n                             [--duration \u003Csec>|auto] [--compositor remotion|mpt] \\\n                             [--capture \u003Cpath>] \\\n                             [--source file|web] [--url \u003Curl>] [--device \u003Cname>] \\\n                             [--ready-selector \u003Ccss>] [--show-cursor] [--polish] \\\n                             [--capture-timeout \u003Csec>] [--capture-stop duration:\u003Csec>|selector:\u003Ccss>] \\\n                             [--out \u003Cdir>] [--allow-external-out] \\\n                             [--max-usd \u003Cn>] [--seed \u003Cn>] [--timeout 600] [-y] \\\n                             [--dry-run] [--script \u003Cpath>] \\\n                             [--format text|json] [--no-brief-in-manifest]\n# --script: inject the agent-authored script.json (agent-as-key). Without it the\n#   CLI builds its own skeleton script from the brief — always pass the script\n#   the agent wrote so narration\u002Fon-screen text\u002Fvisual prompts are honored.\n# --source web: headed browser at --url; capture size derived from --aspect\u002F--device (no hardcoded size).\n# A human drives the on-screen flow; press ENTER to stop. NO credential automation. --url\u002Ftokens masked.\n# Non-interactive (CI \u002F -y \u002F no TTY) or unresolvable Playwright -> falls back to the guided protocol (no hang).\n# --capture-stop gives CI a non-interactive stop (duration \u002F selector) in place of the ENTER prompt.\noma video doctor          # readiness report only (no install): Node\u002FChromium\u002FFFmpeg · Remotion project · Pretendard font · MPT · Playwright · Voicebox MCP · oma-image vendors · Pixelle-MCP · Cap\noma video doctor --install             # one-time: vendored Remotion deps + Chrome Headless Shell + Pretendard font fetch (offline -> warn, system-font fallback)\noma video doctor --install-mpt         # one-time: MoneyPrinterTurbo checkout (clone + venv + deps) for --compositor mpt\noma video doctor --install-playwright  # one-time: npm i playwright + chromium (web capture)\noma video list-providers  # availability + key\u002Ffallback status\noma video render \u003CrunDir>  # re-render from render-spec.json (deterministic)\n```\n\n#### Shared Infrastructure (from other skills)\nOther skills call `oma video generate --format json` and parse the JSON envelope (`{exitCode, runDir, manifestPath, scriptPath, renderSpecPath, warnings, error}`) from stdout. There is no `outputs` key — read output\u002Fasset paths from the manifest at `manifestPath`. The deterministic boundary is `render-spec.json` + assets, so a downstream consumer can re-render via `oma video render \u003CrunDir>` without re-running script\u002Fvoice\u002Fvisual generation.\n\n### Output Layout\n\n```\n.agents\u002Fresults\u002Fvideos\u002F\n└── 20260603-143052-ab12cd-shorts\u002F        # {timestamp}-{shortid}-{mode}\n    ├── script.json                        # determinism boundary start\n    ├── timing.json\n    ├── render-spec.json                   # deterministic compute boundary\n    ├── audio\u002F\n    │   └── narration-01.wav               # single narration track (ALL lines joined — not per-scene)\n    ├── visuals\u002F\n    │   └── scene-01.jpg …\n    ├── captions.srt\n    ├── captions.vtt\n    ├── shorts-\u003Cslug>.mp4\n    └── manifest.json                      # reproducibility record\n```\n\n### Audio Sync & Captions Format\n\n- **Narration is one wav**: oma-voice joins every scene line into a single `audio\u002Fnarration-01.wav`, referenced by `render-spec.audio.narration`. There are no per-scene `narration-NN.wav` files.\n- **Timing**: per-line offsets live in `timing.json` (voicebox-stt -> estimated; the `tts-native` and `whisper-cpp` source values are reserved but not yet wired — `TODO(oma-deferred): whisper-cpp`); scene boundaries and caption cues are derived from it.\n- **Captions**: key-free `.srt` (+ `.vtt`) built from `timing.json`; `render-spec.captions.file` points at the `.srt`. The compositor renders **static windowed cues** — the cue active at the current frame, CSS-wrapped (no per-word animation).\n- **Music**: `--music \u003Cpreset>` renders a BGM bed with **Strudel** and mixes it under narration at `render-spec.audio.musicGainDb` (default −18 dB). The bed is generated offline (headless Chrome + `OfflineAudioContext`), so it needs no key, no network, and no audio device — a 30s bed renders in well under a second.\n  - **Presets**: `calm` (sustained pad + arpeggio), `upbeat` (bright plucks), `cinematic` (drone build to a lead), `lofi` (warm chords, swung ticks), `piano` (neoclassical arpeggio). Each preset picks its key and mode from the run `seed`, so the same preset sounds different run to run without a second pattern.\n  - **Artifacts** in the run dir: `music\u002Fbgm.wav` (mixed by the compositor), `music\u002Fbgm.mp3` (preview), `music\u002Fbgm-raw.wav` (pre-master), and `music\u002Fpattern.strudel` — the source that produced them, editable and re-renderable by hand.\n  - **Level**: every bed is normalised to −14 LUFS with a static gain before a peak limiter, so `musicGainDb` means the same thing for every preset. Normalisation is deliberately *not* `loudnorm`'s one-pass mode, which flattens the arrangement arc.\n  - **Opt-in install**: `@strudel\u002F*` is AGPL-3.0-or-later while the oma CLI is MIT, so the deps are never bundled and never installed implicitly. Run `oma video doctor --install-strudel` once. The CLI never imports Strudel — it spawns `resources\u002Fstrudel\u002Frender.mjs` as a subprocess, the same boundary the Remotion \u002F Playwright projects use.\n  - **Fallback**: a missing install, a missing Chrome, or a failed render degrades to *no music* with a warning. The run still succeeds and `audio.music` stays unset (never a dangling `staticFile()` ref).\n  - **Determinism**: the built-in beds are oscillator-only (sine \u002F triangle \u002F square \u002F sawtooth), which render byte-identically on replay. Noise sounds (`white` \u002F `pink` \u002F `brown`) draw from `Math.random()` and would break that, so the templates avoid them.\n\n## References\n\nFollow `resources\u002Fexecution-protocol.md` step by step.\nSee `resources\u002Fvendor-matrix.md` for provider precheck + fallback-chain rules.\nAuthor `--script` files against `resources\u002Fscript-schema.md` (full field reference + example; `schemaVersion: \"1.0\"` is required).\nUse `resources\u002Fprompt-tips.md` for writing effective briefs per mode.\nBefore submitting, run `resources\u002Fchecklist.md`.\nThe vendored Remotion compositor lives at `resources\u002Fremotion\u002F` (see its `README.md`).\nThe web-capture driver lives at `resources\u002Fplaywright\u002Frecord.mjs` (runs as a subprocess under the resolved Playwright; never imported into the CLI).\nThe MPT fallback compositor driver lives at `resources\u002Fmpt\u002Fdriver.py` (consumed by the CLI's mpt-project internals).\n\n### Configuration\n\nProject-specific settings: `config\u002Fvideo-config.yaml`.\nEnv 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).\n\n- Execution steps: `resources\u002Fexecution-protocol.md`\n- Vendor matrix: `resources\u002Fvendor-matrix.md`\n- Prompt tips: `resources\u002Fprompt-tips.md`\n- Checklist: `resources\u002Fchecklist.md`\n- Remotion compositor: `resources\u002Fremotion\u002FREADME.md`\n- Context loading: `..\u002F_shared\u002Fcore\u002Fcontext-loading.md`\n","# Video Agent - Short-form, Explainer & Demo Router\n\n## Scheduling\n\n### Goal\nGenerate finished `.mp4` videos through a key-optional, 3-tier (CLI-first \u002F MCP \u002F guided) provider router while preserving deterministic asset buses (script -> timing -> render-spec), reproducible manifests, cost controls, and capture-path safety.\n\n### Intent signature\n- User asks for a short-form video, shorts\u002Freels clip, TikTok\u002FYouTube Short, explainer, demo, walkthrough, or screencast.\n- User wants a topic, README, code, or data turned into a narrated, captioned video.\n- Another skill needs shared video-generation infrastructure (script -> assets -> render).\n\n### When to use\n\n- Generating short-form video (shorts \u002F reels) from a topic or brief (`--mode shorts`, 9:16)\n- Generating an explainer from a README, code, or data set (`--mode explainer`, 16:9 \u002F 9:16)\n- Producing a demo \u002F walkthrough from a screen capture file (`--mode demo --source file`, 16:9)\n- Supervised headed web-app capture of any URL (`--mode demo --source web --url \u003Curl>`) — 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.\n- Re-rendering an existing run deterministically from `render-spec.json`\n- Other skills needing video-generation infrastructure (shared invocation via `--format json`)\n\n### When NOT to use\n\n- Generating a single still image -> use `oma-image`\n- Generating a slide deck \u002F presentation -> use `oma-slide` (this skill calls it internally for explainer frames)\n- Generating speech audio only (no video) -> use `oma-voice`\n- Non-linear video editing of an existing finished mp4 -> out of scope (OpenCut-MCP deferred)\n- Supervised headed web capture is in-scope (`--source web`); live streaming is out of scope\n- Interactive HTML explainer document (not a video) -> use `oma-explainer`\n\n### Expected inputs\n- A brief (topic \u002F README path \u002F data) plus optional mode, aspect, locale, captions, visual, voice, music, duration, compositor, capture path, seed\n- For `demo` `--source file`: a screen-capture file path (`--capture`) or Cap availability\n- For `demo` `--source web`: a target `--url` (any URL — local\u002Fstaging\u002Fprod), optional `--device`\u002F`--ready-selector`\u002F`--show-cursor`\u002F`--polish`\u002F`--capture-timeout`; capture size is derived from `--aspect`\u002F`--device` (no hardcoded size); a resolvable Playwright + an interactive TTY (else the run falls back to the guided protocol)\n- Authentication\u002Fenvironment state for oma-voice (Voicebox MCP), oma-image vendors, and optional Pexels \u002F Pixelle keys\n\n### Expected outputs\n- A run directory under `.agents\u002Fresults\u002Fvideos\u002F\u003Ctimestamp>-\u003Cshortid>-\u003Cmode>\u002F`\n- Deterministic asset bus: `script.json`, `timing.json`, `render-spec.json`\n- `audio\u002F`, `visuals\u002F`, `captions.srt` \u002F `captions.vtt`, the rendered `\u003Cmode>-\u003Cslug>.mp4`\n- `manifest.json` with providers, asset hashes, cost breakdown, and exit code\n\n```yaml\noutputs:\n  - name: video\n    description: rendered \u003Cmode>-\u003Cslug>.mp4 in the run directory\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002F*.mp4\"\n    required: true\n  - name: manifest\n    description: reproducibility record (providers, asset sha256 hashes, cost breakdown, exit code)\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002Fmanifest.json\"\n    required: true\n  - name: render-spec\n    description: deterministic compute boundary consumed by `oma video render \u003CrunDir>`\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002Frender-spec.json\"\n    required: true\n  - name: captions\n    description: key-free caption tracks aligned to timing.json\n    artifact: \".agents\u002Fresults\u002Fvideos\u002F*\u002Fcaptions.srt\"\n    required: false\n```\n\n### Dependencies\n- `oma video generate` CLI + central error module (exit codes aligned with `oma search fetch`)\n- oma-voice (Voicebox MCP), oma-image, oma-slide as key-free fallback providers\n- Vendored Remotion project at `resources\u002Fremotion\u002F` (compositor)\n- `resources\u002Fvendor-matrix.md`, `resources\u002Fexecution-protocol.md`, `resources\u002Fprompt-tips.md`, `config\u002Fvideo-config.yaml`\n\n### Control-flow features\n- Branches by mode (shorts \u002F explainer \u002F demo), aspect, visual strategy, provider availability, cost threshold, capture requirement, and path safety\n- Runs a per-capability fallback chain (real key\u002Fresource -> key-free fallback) per backend rule 11\n- Reads briefs\u002Fcaptures and writes assets, render-spec, and manifests\n- Calls external resources: Voicebox MCP, oma-image vendors, Remotion toolchain, optional Pexels \u002F Pixelle\n\n## Structural Flow\n\n### Entry\n1. Validate that the brief carries enough mode\u002Ftopic signal (or infer the mode from keywords).\n2. For `demo`, confirm a capture path exists (or Cap is available); otherwise enter the guided protocol.\n3. Resolve defaults from `config\u002Fvideo-config.yaml` -> env vars -> CLI flags; check output path safety and limits.\n\n### Scenes\n1. **PREPARE**: Resolve mode\u002Faspect\u002Flocale, clarify or amplify the brief, choose the visual + compositor strategy.\n2. **ACQUIRE**: Probe provider availability (voice \u002F visual \u002F caption \u002F compositor), validate capture path, check cost.\n3. **ACT**: Run the mode pipeline — script -> (voice ∥ visuals ∥ captions) -> render-spec -> compositor render.\n4. **VERIFY**: Validate every asset-bus schema, manifest hashes, exit code, and the output mp4.\n5. **FINALIZE**: Return the run-dir path, the mp4 path, and any provider\u002Fcoverage warnings.\n\n### Transitions\n- If the brief lacks a clear mode, infer from keywords (shorts\u002Freels -> shorts; README\u002Fcode -> explainer; capture -> demo) and show the user the inferred plan before generating.\n- If the selected visual provider key is absent (Pexels \u002F Pixelle), fall through the chain to the key-free oma-image stills + Ken Burns fallback and annotate coverage.\n- If `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).\n- If `demo` `--source file` has no capture and Cap is unavailable, emit the guided capture protocol and stop (exit code maps to capture-required).\n- If estimated cost (Pixelle \u002F RunningHub credits) exceeds the guardrail, require confirmation unless bypassed.\n\n### Failure and recovery\n- If a provider is unavailable, try the next provider in the capability's `order`; only chain exhaustion is a stage failure.\n- If the Remotion toolchain is not bootstrapped, point the user to `oma video doctor --install` (one-time: deps + headless shell + Pretendard font); fall back to the MPT compositor where applicable (MPT itself needs a one-time `oma video doctor --install-mpt`).\n- If Voicebox MCP is down, fall back to estimated timing (still produces captions). A whisper.cpp hop between the two is reserved but not yet wired (`TODO(oma-deferred): whisper-cpp`).\n- If the brief locale is non-source, translate via oma-translator (key-free); if absent, warn and keep source text.\n\n### Exit\n- Success: `\u003Cmode>-\u003Cslug>.mp4` and `manifest.json` exist in the run directory; all schemas validate.\n- Partial success: video renders with a key-free fallback in place of a paid provider; coverage is annotated in warnings.\n- Failure: no video is produced and the route\u002Fcost\u002Fcapture\u002Fauth\u002Fsafety blocker is explicit in the exit code + manifest.\n\n## Logical Operations\n\n### Actions\n| Action | SSL primitive | Evidence |\n|--------|---------------|----------|\n| Validate brief + mode | `VALIDATE` | Clarification protocol, mode inference |\n| Select provider strategy | `SELECT` | Vendor matrix, `providers.*.order`, availability |\n| Read brief \u002F capture | `READ` | Brief text, `--capture` path |\n| Generate script | `CALL_TOOL` | AgentScriptProvider -> `script.json` |\n| Synthesize narration + timing | `CALL_TOOL` | oma-voice -> `audio\u002F*.wav` + `timing.json` |\n| Produce visuals | `CALL_TOOL` | oma-image \u002F oma-slide \u002F stock -> `visuals\u002F*` |\n| Build captions | `WRITE` | key-free `captions.srt` \u002F `.vtt` from timing |\n| Compose render-spec | `WRITE` | `render-spec.json` (determinism boundary) |\n| Render video | `CALL_TOOL` | Remotion \u002F MPT compositor -> `\u003Cmode>-\u003Cslug>.mp4` |\n| Validate result | `VALIDATE` | Schema parse, manifest hashes, exit code |\n| Report output | `NOTIFY` | Run-dir + mp4 path summary |\n\n### Tools and instruments\n- `oma video generate`, `oma video doctor`, `oma video list-providers`, `oma video render`\n- Provider adapters: AgentScript, oma-voice, oma-image, oma-slide, Pexels, Pixelle, oma-captions, Cap, Remotion, MPT\n- Vendored Remotion project (`resources\u002Fremotion\u002F`), prompt tips, vendor matrix, video config\n\n### Canonical command path\n```bash\noma video doctor\noma video generate \"\u003Cbrief>\" --mode shorts --aspect auto --captions tiktok --format json\n```\n\nExplainer from a README, with a deterministic seed:\n```bash\noma video generate \"explain this project\" --mode explainer --aspect 16:9 --seed 42 --out .\u002Fout\n```\n\nDemo from a screen capture:\n```bash\noma video generate \"feature walkthrough\" --mode demo --capture \u003Cabsolute-path>.mp4\n```\n\nDeterministic re-render from an existing run:\n```bash\noma video render .agents\u002Fresults\u002Fvideos\u002F20260603-143052-ab12cd-shorts\n```\n\n### Resource scope\n| Scope | Resource target |\n|-------|-----------------|\n| `LOCAL_FS` | Briefs, captures, assets, render-spec, run dir, manifests |\n| `PROCESS` | oma-image \u002F oma-slide CLIs, Remotion \u002F MPT, Cap CLI, Playwright web-capture driver (subprocess) |\n| `NETWORK` | Voicebox MCP (localhost), oma-image vendor APIs, the user-supplied `--url` for web capture (masked in logs\u002Fmanifest), optional Pexels \u002F Pixelle \u002F RunningHub |\n| `CREDENTIALS` | oma-image vendor auth, optional `PEXELS_API_KEY` \u002F `RUNNINGHUB_API_KEY`. Web capture handles NO credentials — a human logs in if the flow needs it; nothing is stored or printed. |\n\n### Preconditions\n- Brief carries enough signal for the mode, or the user approves the inferred\u002Famplified plan.\n- Output path is inside `$PWD` (or `--allow-external-out` is set).\n- For `demo` `--source file`: the capture path exists, is absolute\u002F$PWD-guarded, and is a valid format.\n- For `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).\n- Required provider availability holds for the chosen (non-fallback) path, or the fallback is acceptable.\n\n### Effects and side effects\n- Creates a run directory with assets, render-spec, captions, mp4, and manifest.\n- oma-voice plays narration on the speakers as a side effect of synthesis.\n- May call paid or rate-limited providers (Pexels \u002F Pixelle \u002F RunningHub) only when keys are present.\n\n### Guardrails\n\n1. **Clarify or infer before invoking**: if the mode\u002Ftopic is ambiguous, infer the mode from keywords and show the user the plan, or ask. Do NOT silently render from a vague brief. See `Clarification Protocol` below.\n2. **Key-optional dispatch (backend rule 11)**: every external capability has a real (key\u002Fresource) path AND a key-free fallback. Paid providers (Pexels, Pixelle) auto-enable only when their env key is present; otherwise the chain falls through to oma-image stills + Ken Burns. Default providers (oma-voice local, oma-image, oma-slide, Remotion) are key-free, so auto-triggering on keywords is safe.\n3. **Cost guardrail**: confirm before runs whose estimated cost is >= `cost.guardrail_usd` (`$0.20`, configurable) or `--max-usd`. `--yes` \u002F `OMA_VIDEO_YES=1` bypass. Local\u002Ffree paths carry zero cost.\n4. **Path safety**: output paths outside `$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).\n5. **Cancellable**: SIGINT\u002FSIGTERM aborts in-flight provider calls, the render, and the orchestrator.\n6. **Deterministic outputs**: `render-spec.json` + asset files (+ seed + embedded Pretendard font) are the determinism boundary. `oma video doctor --install` fetches the Pretendard woff2 once; if offline, the render gracefully falls back to system fonts, and byte-identical output across machines is only guaranteed once the font is present. Re-rendering the same render-spec is byte-stable; `OMA_VIDEO_MOCK=1` replays golden fixtures.\n7. **Limits**: `limits.max_duration_sec` = 180, `limits.max_scenes` = 40 (wall-time + memory bound).\n8. **Community-MCP consent**: Pixelle-MCP is off by default and requires one-time explicit consent + source review before connecting; RunningHub credits gate on `--max-usd`.\n9. **Demo is human-in-the-loop**: capture is performed by a human. For `--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.\n10. **Web-capture security**: NO credential automation of any kind — if a flow needs a login, a human performs it. The driver runs as a subprocess under the resolved Playwright (never imported into the CLI). The `--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 \u002F new tab \u002F redirect) is recorded generically, with no assumption about the flow's shape.\n11. **Web capture is key-optional + non-blocking**: web capture is the real branch; the guided protocol is the fallback when Playwright is unresolvable OR there is no interactive TTY (CI \u002F `-y` \u002F no stdin) — the run falls back to guided and never hangs. Live capture is outside the determinism boundary, so the manifest records `nondeterministic: true`.\n12. **Headed capture needs a display**: web capture launches a **headed** Chromium so the human can drive the flow. On display-less hosts (CI \u002F Linux without X), pass `--capture-stop duration:\u003Csec>|selector:\u003Ccss>` — the driver then runs headless (`resources\u002Fplaywright\u002Frecord.mjs --headless 1`) — or expect a capture error \u002F guided fallback.\n13. **Run-dir retention**: `.agents\u002Fresults\u002Fvideos\u002F\u003Crun>\u002F` accumulates one directory per run (assets + mp4 + manifest) and is **never auto-pruned**; the user deletes old run directories manually.\n14. **Exit codes align with `oma search fetch`** (0 ok, 1 generic, 2 safety, 3 not-found, 4 invalid-input, 5 auth-required, 6 timeout).\n\n### Clarification Protocol\n\nBefore invoking `oma video generate`, the calling agent runs this checklist. **If any answer is \"no \u002F unknown\", clarify or infer-and-confirm with the user first.**\n\n**Required signal (must be present or inferable):**\n- [ ] **Mode**: shorts \u002F explainer \u002F demo? Infer from keywords (shorts\u002Freels\u002F쇼츠\u002F릴스 -> shorts; README\u002Fcode\u002Fdata\u002Fexplain\u002F설명 -> explainer; demo\u002Fwalkthrough\u002Fcapture\u002F데모 -> demo).\n- [ ] **Topic \u002F source**: what is the video about? (a topic, a README\u002Fcode path, a capture file, or — for `demo` `--source web` — a `--url`)\n- [ ] **For `demo`**: `--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**.\n\n**Strongly recommended (ask if absent AND not inferable):**\n- [ ] **Aspect**: `9:16` (shorts\u002Freels), `16:9` (explainer\u002Fdemo), `1:1`, or `auto` (snaps to the mode default).\n- [ ] **Locale**: narration + caption language (default from config; translated via oma-translator when non-source).\n- [ ] **Captions**: `tiktok` (centered, static windowed cues), `lower-third`, or `none`.\n- [ ] **Duration**: target seconds (\u003C= 180) or `auto` (derived from the script).\n- [ ] **Voice \u002F music**: voice profile or `none`; music `upbeat` \u002F `calm` \u002F `none`. **The default voice is `none` → a silent video with estimated caption timing.** Pass `--voice \u003Cprofile>` (a Voicebox profile) whenever narration is expected. Music is rendered offline by Strudel and mixed at −18 dB; it needs a one-time `oma video doctor --install-strudel` and degrades to no music without it.\n\n**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:\n\n> User: \"make a short about Jeju coffee\"\n> 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\u002Faspect\u002Fvoice?\"\n\nSkip clarification when the user authored a full brief (mode + topic + aspect + captions). Respect their flags verbatim.\n\n**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.\n\n### Modes\n\n| Mode | Aspect | Source | Default visual | Compositor | Output |\n|------|:---:|--------|----------------|------------|--------|\n| `shorts` | 9:16 | synthetic (topic) | oma-image stills + Ken Burns; Pexels (key) · Pixelle AIGC (key) opt | Remotion · MPT alt | `shorts-\u003Cslug>.mp4` |\n| `explainer` | 16:9 \u002F 9:16 | README · code · data | oma-slide frames + oma-image diagrams + code | Remotion (deterministic) | `explainer-\u003Cslug>.mp4` |\n| `demo` | 16:9 | `--source file` (Cap \u002F capture file) · `--source web` (headed browser at `--url`) | raw footage (default) · Remotion intro · zoom · callouts (`--polish`) | Remotion polish | `demo-\u003Cslug>.mp4` |\n\n### 3-Tier Integration\n\n| Tier | Surface | Providers | Trigger |\n|:---:|---------|-----------|---------|\n| 1 | CLI-first (subprocess, deterministic) | Remotion render, MPT, oma-image, oma-slide, oma-voice | always available (key-free defaults) |\n| 2 | MCP | Voicebox MCP (voice\u002Ftiming), Pixelle-MCP (AIGC, off by default) | MCP server reachable; Pixelle needs explicit consent + key |\n| 3 | Guided (human-in-the-loop) | Playwright headed web capture (`--source web`, human drives the flow), Cap (capture), guided protocol fallback | `demo` mode; web capture needs a resolvable Playwright + a TTY (else guided protocol) |\n\n### Invocation\n\n#### Standalone\n```\n\u002Foma-video make a 30s short about Jeju coffee\n\u002Foma-video --mode explainer --aspect 16:9 explain this project from the README\n\u002Foma-video --mode demo --source file --capture ~\u002Frecordings\u002Fwalkthrough.mp4 feature demo\n\u002Foma-video --mode demo --source web --url http:\u002F\u002Flocalhost:3000 record my app flow\n\u002Foma-video --mode demo --source web --url \u003Curl> --ready-selector \"#app\" --polish onboarding clip\n```\n\n#### Shell CLI\n```\noma video generate \"\u003Cbrief>\" [--mode shorts|explainer|demo] \\\n                             [--aspect 9:16|16:9|1:1|auto] [--locale \u003Clang>] \\\n                             [--captions tiktok|lower-third|none] \\\n                             [--visual auto|generate|stock|aigc|slide] \\\n                             [--voice \u003Cprofile>|none] [--music upbeat|calm|cinematic|lofi|piano|none] \\\n                             [--duration \u003Csec>|auto] [--compositor remotion|mpt] \\\n                             [--capture \u003Cpath>] \\\n                             [--source file|web] [--url \u003Curl>] [--device \u003Cname>] \\\n                             [--ready-selector \u003Ccss>] [--show-cursor] [--polish] \\\n                             [--capture-timeout \u003Csec>] [--capture-stop duration:\u003Csec>|selector:\u003Ccss>] \\\n                             [--out \u003Cdir>] [--allow-external-out] \\\n                             [--max-usd \u003Cn>] [--seed \u003Cn>] [--timeout 600] [-y] \\\n                             [--dry-run] [--script \u003Cpath>] \\\n                             [--format text|json] [--no-brief-in-manifest]\n# --script: inject the agent-authored script.json (agent-as-key). Without it the\n#   CLI builds its own skeleton script from the brief — always pass the script\n#   the agent wrote so narration\u002Fon-screen text\u002Fvisual prompts are honored.\n# --source web: headed browser at --url; capture size derived from --aspect\u002F--device (no hardcoded size).\n# A human drives the on-screen flow; press ENTER to stop. NO credential automation. --url\u002Ftokens masked.\n# Non-interactive (CI \u002F -y \u002F no TTY) or unresolvable Playwright -> falls back to the guided protocol (no hang).\n# --capture-stop gives CI a non-interactive stop (duration \u002F selector) in place of the ENTER prompt.\noma video doctor          # readiness report only (no install): Node\u002FChromium\u002FFFmpeg · Remotion project · Pretendard font · MPT · Playwright · Voicebox MCP · oma-image vendors · Pixelle-MCP · Cap\noma video doctor --install             # one-time: vendored Remotion deps + Chrome Headless Shell + Pretendard font fetch (offline -> warn, system-font fallback)\noma video doctor --install-mpt         # one-time: MoneyPrinterTurbo checkout (clone + venv + deps) for --compositor mpt\noma video doctor --install-playwright  # one-time: npm i playwright + chromium (web capture)\noma video list-providers  # availability + key\u002Ffallback status\noma video render \u003CrunDir>  # re-render from render-spec.json (deterministic)\n```\n\n#### Shared Infrastructure (from other skills)\nOther skills call `oma video generate --format json` and parse the JSON envelope (`{exitCode, runDir, manifestPath, scriptPath, renderSpecPath, warnings, error}`) from stdout. There is no `outputs` key — read output\u002Fasset paths from the manifest at `manifestPath`. The deterministic boundary is `render-spec.json` + assets, so a downstream consumer can re-render via `oma video render \u003CrunDir>` without re-running script\u002Fvoice\u002Fvisual generation.\n\n### Output Layout\n\n```\n.agents\u002Fresults\u002Fvideos\u002F\n└── 20260603-143052-ab12cd-shorts\u002F        # {timestamp}-{shortid}-{mode}\n    ├── script.json                        # determinism boundary start\n    ├── timing.json\n    ├── render-spec.json                   # deterministic compute boundary\n    ├── audio\u002F\n    │   └── narration-01.wav               # single narration track (ALL lines joined — not per-scene)\n    ├── visuals\u002F\n    │   └── scene-01.jpg …\n    ├── captions.srt\n    ├── captions.vtt\n    ├── shorts-\u003Cslug>.mp4\n    └── manifest.json                      # reproducibility record\n```\n\n### Audio Sync & Captions Format\n\n- **Narration is one wav**: oma-voice joins every scene line into a single `audio\u002Fnarration-01.wav`, referenced by `render-spec.audio.narration`. There are no per-scene `narration-NN.wav` files.\n- **Timing**: per-line offsets live in `timing.json` (voicebox-stt -> estimated; the `tts-native` and `whisper-cpp` source values are reserved but not yet wired — `TODO(oma-deferred): whisper-cpp`); scene boundaries and caption cues are derived from it.\n- **Captions**: key-free `.srt` (+ `.vtt`) built from `timing.json`; `render-spec.captions.file` points at the `.srt`. The compositor renders **static windowed cues** — the cue active at the current frame, CSS-wrapped (no per-word animation).\n- **Music**: `--music \u003Cpreset>` renders a BGM bed with **Strudel** and mixes it under narration at `render-spec.audio.musicGainDb` (default −18 dB). The bed is generated offline (headless Chrome + `OfflineAudioContext`), so it needs no key, no network, and no audio device — a 30s bed renders in well under a second.\n  - **Presets**: `calm` (sustained pad + arpeggio), `upbeat` (bright plucks), `cinematic` (drone build to a lead), `lofi` (warm chords, swung ticks), `piano` (neoclassical arpeggio). Each preset picks its key and mode from the run `seed`, so the same preset sounds different run to run without a second pattern.\n  - **Artifacts** in the run dir: `music\u002Fbgm.wav` (mixed by the compositor), `music\u002Fbgm.mp3` (preview), `music\u002Fbgm-raw.wav` (pre-master), and `music\u002Fpattern.strudel` — the source that produced them, editable and re-renderable by hand.\n  - **Level**: every bed is normalised to −14 LUFS with a static gain before a peak limiter, so `musicGainDb` means the same thing for every preset. Normalisation is deliberately *not* `loudnorm`'s one-pass mode, which flattens the arrangement arc.\n  - **Opt-in install**: `@strudel\u002F*` is AGPL-3.0-or-later while the oma CLI is MIT, so the deps are never bundled and never installed implicitly. Run `oma video doctor --install-strudel` once. The CLI never imports Strudel — it spawns `resources\u002Fstrudel\u002Frender.mjs` as a subprocess, the same boundary the Remotion \u002F Playwright projects use.\n  - **Fallback**: a missing install, a missing Chrome, or a failed render degrades to *no music* with a warning. The run still succeeds and `audio.music` stays unset (never a dangling `staticFile()` ref).\n  - **Determinism**: the built-in beds are oscillator-only (sine \u002F triangle \u002F square \u002F sawtooth), which render byte-identically on replay. Noise sounds (`white` \u002F `pink` \u002F `brown`) draw from `Math.random()` and would break that, so the templates avoid them.\n\n## References\n\nFollow `resources\u002Fexecution-protocol.md` step by step.\nSee `resources\u002Fvendor-matrix.md` for provider precheck + fallback-chain rules.\nAuthor `--script` files against `resources\u002Fscript-schema.md` (full field reference + example; `schemaVersion: \"1.0\"` is required).\nUse `resources\u002Fprompt-tips.md` for writing effective briefs per mode.\nBefore submitting, run `resources\u002Fchecklist.md`.\nThe vendored Remotion compositor lives at `resources\u002Fremotion\u002F` (see its `README.md`).\nThe web-capture driver lives at `resources\u002Fplaywright\u002Frecord.mjs` (runs as a subprocess under the resolved Playwright; never imported into the CLI).\nThe MPT fallback compositor driver lives at `resources\u002Fmpt\u002Fdriver.py` (consumed by the CLI's mpt-project internals).\n\n### Configuration\n\nProject-specific settings: `config\u002Fvideo-config.yaml`.\nEnv 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).\n\n- Execution steps: `resources\u002Fexecution-protocol.md`\n- Vendor matrix: `resources\u002Fvendor-matrix.md`\n- Prompt tips: `resources\u002Fprompt-tips.md`\n- Checklist: `resources\u002Fchecklist.md`\n- Remotion compositor: `resources\u002Fremotion\u002FREADME.md`\n- Context loading: `..\u002F_shared\u002Fcore\u002Fcontext-loading.md`\n",{"name":5,"description":7},"main","0debaec9469b8a9289d77b8ce5c3143c4a656b16",".agents\u002Fskills\u002Foma-video",0,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac","https:\u002F\u002Fgithub.com\u002Fmrmarbury","FreeBSD admin, Elixir & Erlang Dev, Rubyist, Skateboarder, Musician","2026-11-07 06:23:43",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":67},[57,60,63],{"tool":58,"command":59},"npx","npx skills add mrmarbury\u002FPalmSync4Mac --skill oma-video",{"tool":61,"command":62},"bunx","bunx skills add mrmarbury\u002FPalmSync4Mac --skill oma-video",{"tool":64,"command":65},"pnpm","pnpm dlx skills add mrmarbury\u002FPalmSync4Mac --skill oma-video","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002FSKILL.md",true,[69,75,79,83,87,91,95,101,105,109,115,119,123,127,131,135,139,143,147,151,155,159,163,167,171,175,179,183,187,191],{"path":70,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":73,"sourceHtmlUrl":74},"agents\u002Fopenai.yaml","REFERENCE","参考文档",102,"https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fplugins\u002Fmatt-pocock\u002Fskills\u002Fcodebase-design\u002Fagents\u002Fopenai.yaml",{"path":76,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":77,"sourceHtmlUrl":78},"config\u002Fvideo-config.yaml",1421,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fconfig\u002Fvideo-config.yaml",{"path":80,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":81,"sourceHtmlUrl":82},"DEEPENING.md",2553,"https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fplugins\u002Fmatt-pocock\u002Fskills\u002Fcodebase-design\u002FDEEPENING.md",{"path":84,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":85,"sourceHtmlUrl":86},"DESIGN-IT-TWICE.md",2664,"https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fplugins\u002Fmatt-pocock\u002Fskills\u002Fcodebase-design\u002FDESIGN-IT-TWICE.md",{"path":88,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":89,"sourceHtmlUrl":90},"resources\u002Fchecklist.md",2257,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fchecklist.md",{"path":92,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":93,"sourceHtmlUrl":94},"resources\u002Fexecution-protocol.md",7380,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fexecution-protocol.md",{"path":96,"resourceType":97,"resourceTypeDesc":98,"sizeBytes":99,"sourceHtmlUrl":100},"resources\u002Fmpt\u002Fdriver.py","SCRIPT","脚本",12049,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fmpt\u002Fdriver.py",{"path":102,"resourceType":97,"resourceTypeDesc":98,"sizeBytes":103,"sourceHtmlUrl":104},"resources\u002Fplaywright\u002Frecord.mjs",17728,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fplaywright\u002Frecord.mjs",{"path":106,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":107,"sourceHtmlUrl":108},"resources\u002Fprompt-tips.md",4578,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fprompt-tips.md",{"path":110,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":113,"sourceHtmlUrl":114},"resources\u002Fremotion\u002F.gitignore","OTHER","其他",180,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002F.gitignore",{"path":116,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":117,"sourceHtmlUrl":118},"resources\u002Fremotion\u002Fpackage.json",805,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fpackage.json",{"path":120,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":121,"sourceHtmlUrl":122},"resources\u002Fremotion\u002Fpublic\u002Ffonts\u002FREADME.md",1332,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fpublic\u002Ffonts\u002FREADME.md",{"path":124,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":125,"sourceHtmlUrl":126},"resources\u002Fremotion\u002FREADME.md",4571,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002FREADME.md",{"path":128,"resourceType":97,"resourceTypeDesc":98,"sizeBytes":129,"sourceHtmlUrl":130},"resources\u002Fremotion\u002Fremotion.config.ts",473,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fremotion.config.ts",{"path":132,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":133,"sourceHtmlUrl":134},"resources\u002Fremotion\u002Fsrc\u002Fcomponents\u002FCaptions.tsx",3609,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Fcomponents\u002FCaptions.tsx",{"path":136,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":137,"sourceHtmlUrl":138},"resources\u002Fremotion\u002Fsrc\u002Fcomponents\u002FScene.tsx",2570,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Fcomponents\u002FScene.tsx",{"path":140,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":141,"sourceHtmlUrl":142},"resources\u002Fremotion\u002Fsrc\u002Fcomponents\u002FVideoBase.tsx",2281,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Fcomponents\u002FVideoBase.tsx",{"path":144,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":145,"sourceHtmlUrl":146},"resources\u002Fremotion\u002Fsrc\u002Fcompositions\u002FDemo.tsx",566,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Fcompositions\u002FDemo.tsx",{"path":148,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":149,"sourceHtmlUrl":150},"resources\u002Fremotion\u002Fsrc\u002Fcompositions\u002FExplainer.tsx",423,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Fcompositions\u002FExplainer.tsx",{"path":152,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":153,"sourceHtmlUrl":154},"resources\u002Fremotion\u002Fsrc\u002Fcompositions\u002FShorts.tsx",430,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Fcompositions\u002FShorts.tsx",{"path":156,"resourceType":97,"resourceTypeDesc":98,"sizeBytes":157,"sourceHtmlUrl":158},"resources\u002Fremotion\u002Fsrc\u002Findex.ts",266,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Findex.ts",{"path":160,"resourceType":97,"resourceTypeDesc":98,"sizeBytes":161,"sourceHtmlUrl":162},"resources\u002Fremotion\u002Fsrc\u002Fload-fonts.ts",2648,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Fload-fonts.ts",{"path":164,"resourceType":97,"resourceTypeDesc":98,"sizeBytes":165,"sourceHtmlUrl":166},"resources\u002Fremotion\u002Fsrc\u002Frender-spec.ts",3011,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002Frender-spec.ts",{"path":168,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":169,"sourceHtmlUrl":170},"resources\u002Fremotion\u002Fsrc\u002FRoot.tsx",2431,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Fsrc\u002FRoot.tsx",{"path":172,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":173,"sourceHtmlUrl":174},"resources\u002Fremotion\u002Ftsconfig.json",415,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fremotion\u002Ftsconfig.json",{"path":176,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":177,"sourceHtmlUrl":178},"resources\u002Fscript-schema.md",3597,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fscript-schema.md",{"path":180,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":181,"sourceHtmlUrl":182},"resources\u002Fstrudel\u002Fpackage.json",477,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fstrudel\u002Fpackage.json",{"path":184,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":185,"sourceHtmlUrl":186},"resources\u002Fstrudel\u002Fpage.html",3088,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fstrudel\u002Fpage.html",{"path":188,"resourceType":97,"resourceTypeDesc":98,"sizeBytes":189,"sourceHtmlUrl":190},"resources\u002Fstrudel\u002Frender.mjs",10017,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fstrudel\u002Frender.mjs",{"path":192,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":193,"sourceHtmlUrl":194},"resources\u002Fvendor-matrix.md",6413,"https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-video\u002Fresources\u002Fvendor-matrix.md",[196,223,251,277,302,331],{"skillNo":197,"name":198,"nameZh":6,"description":199,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":200,"categories":201,"keywords":202,"publishedAt":42},"01M6WJZMN4HV76T0Y2PYDAAD7Q","oma-translator","Context-aware translation that preserves tone, style, and natural word order. Use when translating UI strings, documentation, marketing copy, or any multilingual content. Infers register, domain, and style from the source text and surrounding codebase context.","https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-translation\u002FSKILL.md",[],[203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222],"translator","oma translator","documentation","ui","marketing","Word","text","context","use","multilingual","translation","domain","tone","style","register","copy","strings","source","codebase","when",{"skillNo":224,"name":225,"nameZh":6,"description":226,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":227,"categories":228,"keywords":232,"publishedAt":42},"01M6WJZ5W60XSDDE72AW5E85GT","oma-skill-creator","Create or update OMA skills in the SSL-lite human-readable format. Use when adding a new `.agents\u002Fskills\u002F{skill-name}\u002FSKILL.md`, converting an existing skill to the standardized Scheduling \u002F Structural Flow \u002F Logical Operations \u002F References structure, or validating whether a skill has enough routing, execution, resource, and safety detail.","https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-skill-creation\u002FSKILL.md",[229],{"categoryNo":230,"categoryName":231,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[233,234,235,236,237,238,239,240,241,242,211,243,244,245,246,247,248,249,250,222],"skill creator","oma skill creator","creator","create","update","routing","ssl","flow","execution","Safety","scheduling","references","existing skill","structure","human","structural","detail","Existing",{"skillNo":252,"name":253,"nameZh":6,"description":254,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":255,"categories":256,"keywords":258,"publishedAt":42},"01M6WJYHKKTDG9RT9A6ZWCT29A","oma-orchestrator","Automated multi-agent orchestrator that spawns CLI subagents in parallel, coordinates via MCP Memory, and monitors progress. Use for orchestration, parallel execution, and automated multi-agent workflows.","https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-orchestration\u002FSKILL.md",[257],{"categoryNo":230,"categoryName":231,"taxonomyType":21,"taxonomyTypeDesc":22},[259,260,261,262,263,264,265,241,266,267,268,211,269,270,271,272,273,274,275,276],"oma orchestrator","orchestrator","MCP","cli","memory","orchestration","workflows","multi-agent","parallel","subagents","agent orchestrator","parallel execution","coordinates","agent workflows","progress","via","multi","for",{"skillNo":278,"name":279,"nameZh":6,"description":280,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":281,"categories":282,"keywords":286,"publishedAt":42},"01M6WJXXDQ99RCQ3S4GW5D42Q4","oma-explainer","Turn a code change (diff, PR, branch, commit range) into a rich, self-contained interactive HTML explainer with Background \u002F Intuition \u002F Code \u002F Quiz sections. Use for explain, walkthrough, code-change explanation, diff\u002FPR\u002Fbranch explainer requests — 설명서, 해설, コード解説, 代码讲解. Produces a single offline-capable HTML file with diagrams, callouts, and an accessible quiz.","https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-explanation\u002FSKILL.md",[283],{"categoryNo":284,"categoryName":285,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[37,287,288,289,290,29,291,292,36,293,294,211,295,296,297,298,299,276,300,301],"oma explainer","change","commit","pr","offline","file","branch","interactive","html","diff","diagrams","self","quiz","rich","single",{"skillNo":303,"name":304,"nameZh":6,"description":305,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":306,"categories":307,"keywords":311,"publishedAt":42},"01M6WJWQC0CTFQWQKQ2EZYXVGJ","oma-academic-writer","Academic writing specialist for publication-grade English prose. Drafts, revises, and audits essays, reports, analysis sections, executive summaries, conclusions, and literature reviews while enforcing sentence-structure variation, high-frequency academic verbs, calibrated hedging, and anti-AI stylistic compliance. USE for academic writing, essay polish, paragraph rewrite, prose revision against any rubric tier (HD\u002FD\u002FC, A\u002FB\u002FC, top-band\u002Fmid-band, etc.), anti-AI audit, reverse outlining, claim-evidence mapping, and rubric enforcement on assignments.","https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Foma-academic-writing\u002FSKILL.md",[308],{"categoryNo":309,"categoryName":310,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",[312,313,314,315,316,317,318,319,320,321,322,246,323,324,325,326,327,328,329,330],"oma academic writer","writer","Academic","academic writer","writing","audit","analysis","polish","reports","ai audit","claim","Anti-AI","english","literature","essays","essay","reviews","drafts","top",{"skillNo":332,"name":333,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":334,"categories":335,"keywords":336,"publishedAt":42},"01M6BYY6K38NQSE2BXHWM0ZGRC","work","https:\u002F\u002Fgithub.com\u002Fmrmarbury\u002FPalmSync4Mac\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fwork\u002FSKILL.md",[],[333]]