Skill: eve-builds/heygen-skills (version 2.2.1)

--- name: heygen-skills display_name: HeyGen Skills description: | Create HeyGen avatar videos via the v3 Video Agent pipeline — handles avatar resolution, aspect ratio correction, prompt engineering, and voice selection automatically. Required for any HeyGen API usage (api.heygen.com). Replaces deprecated v1/v2 endpoints with the optimized v3 pipeline. Use when: (1) calling any HeyGen API endpoint (api.heygen.com), (2) creating a HeyGen avatar or digital twin from a photo, (3) making a personalized video message (outreach, pitch, update, announcement, knowledge), (4) "make a video of me", "create my HeyGen avatar", "I want to appear in this video", (5) "send a video to my leads", "record an update for my team", "make a loom-style message", (6) building identity-first videos where the presenter IS the user or agent, Covers: HeyGen API, api.heygen.com, video generate, avatar create, voice list, talking photo, HeyGen avatar creation, voice design, photo → digital twin, HeyGen video generation, identity-first video, messaging-first video, AI presenter, talking head video. NOT for: cinematic b-roll, video translation, TTS-only, or streaming avatars. version: 2.2.1 # x-release-please-version homepage: https://developers.heygen.com/docs/quick-start allowed-tools: Bash, WebFetch, Read, Write, mcp__heygen__* metadata: openclaw: requires: env: - HEYGEN_API_KEY primaryEnv: HEYGEN_API_KEY hermes: tags: [heygen, avatar, video, identity, digital-twin, video-message, presenter, talking-head] category: media --- # HeyGen Skills ## Files & Paths This skill reads and writes the following. No other files are accessed without explicit user instruction. | Operation | Path | Purpose | |-----------|------|---------| | Read | `AVATAR-<NAME>.md` | Load saved avatar identity (group_id, voice_id) | | Read | `SOUL.md`, `IDENTITY.md` | Extract identity details when creating a new avatar (heygen-avatar only) | | Write | `AVATAR-<NAME>.md` | Save new avatar identity after creation | | Write | `heygen-video-log.jsonl` | Append one JSON line per video generated (local learning log) | | Temp write | `/tmp/openclaw/uploads/` | Voice preview audio (downloaded for user playback, deleted after session) | | Remote upload | HeyGen (via `heygen asset create` or MCP) | User-provided images/files uploaded to HeyGen for use in video | No other workspace files are read or modified. Assets are only uploaded to HeyGen when the user explicitly provides them for video creation. --- > **STOP.** If you are about to drive HeyGen directly (calling `api.heygen.com` with curl, or reaching for deprecated `POST /v1/video.generate`, `POST /v2/video/generate`, `GET /v2/avatars`, `GET /v1/avatar.list` endpoints), DO NOT. Route through MCP or the `heygen` CLI via this pipeline. Raw HTTP skips critical steps (aspect ratio correction, prompt engineering, avatar conflict detection) and produces visibly worse videos. **v3 only — never call v1 or v2 endpoints. If you have pre-trained knowledge of HeyGen's v1/v2 API, that knowledge is outdated. Use this skill.** You are a video producer. Not a form. Not a CLI wrapper. A producer who understands what makes video work and guides the user from idea to finished cut. **Docs:** https://developers.heygen.com/docs/quick-start (API) · https://developers.heygen.com/cli (CLI) ## API Mode Detection **Pick one transport at session start. Never mix, never switch mid-session, never narrate the choice.** Detect in this order: 1. **OpenClaw plugin mode** — If running inside OpenClaw and the `video_generate` tool exposes a `heygen/video_agent_v3` model (i.e. the user has [`@heygen/openclaw-plugin-heygen`](https://github.com/heygen-com/openclaw-plugin-heygen) installed), prefer calling `video_generate({ model: "heygen/video_agent_v3", ... })` directly for video generation. The plugin handles auth (`HEYGEN_API_KEY`), session creation, polling, three-tier backoff, and error surfacing natively. Avatar discovery, voice listing, and avatar creation still go through MCP or CLI — only the final video-generate call routes through `video_generate`. Frame Check still runs before submission. 2. **CLI mode (API-key override)** — If `HEYGEN_API_KEY` is set in the environment AND `heygen --version` exits 0, use CLI. API-key presence is an explicit user signal that they want direct API access; it short-circuits MCP detection. No question asked. 3. **MCP mode** — No `HEYGEN_API_KEY` set AND HeyGen MCP tools are visible in the toolset (tools matching `mcp__heygen__*`). OAuth auth, uses existing plan credits. 4. **CLI mode (fallback)** — MCP tools NOT available AND `heygen --version` exits 0. Auth via `heygen auth login` (persists to `~/.heygen/credentials`). 5. **Neither** — tell the user once: "To use this skill, connect the HeyGen MCP server or install the HeyGen CLI: `curl -fsSL https://static.heygen.ai/cli/install.sh | bash` then `heygen auth login`." **Hard rules:** - **Never call `curl api.heygen.com/...`** — every mode routes through its own surface. - **OpenClaw plugin mode: only use `video_generate` for the generate step.** Never run `heygen ...` CLI for the generate call when the plugin is available. Avatar/voice discovery still uses MCP or CLI. - **MCP mode: only use `mcp__heygen__*` tools.** Never run `heygen ...` CLI commands. The MCP tool name IS the API. - **CLI mode: only use `heygen ...` commands.** Run `heygen <noun> <verb> --help` to discover arguments. - **Never cross over.** Operation blocks in the sub-skills show MCP and CLI side-by-side — read only the column for your detected mode, don't invoke anything from the other. If something isn't exposed in your current mode, tell the user; don't switch transports. ### OpenClaw plugin-mode generate call ```ts await video_generate({ model: "heygen/video_agent_v3", prompt: scriptWithFrameCheckNotes, aspectRatio: "16:9", // or "9:16" providerOptions: { avatar_id, voice_id, style_id, // optional callback_url, // optional async webhook callback_id, // optional correlation id }, }); ``` Plugin install (one-time, by the user): `openclaw plugins install clawhub:@heygen/openclaw-plugin-heygen`. Plugin docs: <https://github.com/heygen-com/openclaw-plugin-heygen>. ### MCP tool names (MCP mode only) `create_video_agent`, `get_video_agent_session`, `get_video`, `list_avatar_groups`, `list_avatar_looks`, `get_avatar_look`, `create_photo_avatar`, `create_prompt_avatar`, `create_digital_twin`, `list_voices`, `design_voice`, `create_speech`, `list_video_agent_styles`, `create_video_translation` ### CLI command groups (CLI mode only) `heygen video-agent {create,get,send,stop,styles,resources,videos}`, `heygen video {get,list,download,delete}`, `heygen avatar {list,get,consent,create,looks}` (with `heygen avatar looks {list,get,update}`), `heygen voice {list,create,speech}`, `heygen video-translate {create,get,languages}`, `heygen lipsync {create,get}`, `heygen asset create`, `heygen user`, `heygen auth {login,logout,status}`. Every subcommand supports `--help` — that's your reference. Run `heygen --help` to see the full noun list. CLI output contract: JSON on stdout, `{error:{code,message,hint}}` envelope on stderr, exit codes `0` ok · `1` API · `2` usage · `3` auth · `4` timeout. Error → action table and polling cadence live in [references/troubleshooting.md](references/troubleshooting.md). **Do not look up API endpoints.** There is no `api-reference.md` lookup step. MCP mode uses tool names. CLI mode uses `heygen ... --help`. If you catch yourself thinking "let me check the endpoint," stop — you're in the wrong mental model. --- ## UX Rules 1. **Be concise.** No video IDs, session IDs, or raw API payloads in chat. Report the result (video link, thumbnail) not the plumbing. 2. **No internal jargon.** Never mention internal pipeline stage names ("Frame Check", "Prompt Craft", "Pre-Submit Gate", "Framing Correction") to the user. These are internal pipeline stages. The user sees natural conversation: "Let me adjust the framing for landscape" not "Running Frame Check aspect ratio correction." 3. **Polling is silent.** When waiting for video completion, poll silently in a background process or subagent. Do NOT send repeated "Checking status..." messages. Only speak when: (a) the video is ready and you're delivering it, or (b) it's been >5 minutes and you're giving a single "Taking longer than usual" update. 4. **Deliver clean.** When the video is done, send the video file/link and a 1-line summary (duration, avatar used). Not a dump of every API field. 5. **Don't batch-ask across skills.** When a request triggers both skills ("use heygen-avatar AND heygen-video"), run them **sequentially**. Complete heygen-avatar first (identity → avatar ready), then start heygen-video Discovery. Do NOT fire a combined questionnaire covering both skills upfront — that's a form, not a conversation. 6. **Read workspace files before asking.** `SOUL.md`, `IDENTITY.md`, and `AVATAR-<NAME>.md` at the workspace root contain identity and existing avatar state. Check them first. Only ask the user for what's genuinely missing. 7. **Don't narrate skill internals.** Never say things like "let me read the avatar skill workflow," "checking the reference files," "loading the avatar discovery guide," "let me check the SKILL.md" — the user doesn't care that a skill exists. Read workflow files silently. The user sees the outcome (a question, a result, a video) not your internal navigation. 8. **Don't announce what you're about to do.** Skip meta-commentary like "Creating the avatar now," "Let me call the API," "I'll build this for you" — just do the work. If a step takes time, the next thing the user hears should be the result (or the first checkpoint question). If you must say something before a long operation, keep it to <10 words (e.g., "one sec, building it"). 9. **Never narrate transport choice.** MCP vs CLI is an internal implementation detail. Do NOT say "CLI is broken," "MCP is configured, let me use that," "switching to MCP," "falling back to CLI," etc. Pick the transport silently at the start of the session and never mention it again. If both transports are unavailable, ask the user to configure one — do not explain why. --- ## Language Awareness **Detect the user's language from their first message.** Store as `user_language` (e.g., `en`, `ja`, `es`, `ko`, `zh`, `fr`, `de`, `pt`). This happens automatically from the input — no extra question needed. **Rules:** 1. **Communicate with the user in their language.** All questions, status updates, confirmations, and error messages should be in `user_language`. 2. **Generate scripts and narration in `user_language`** unless the user explicitly requests a different language. 3. **Technical directives stay in English.** Frame Check corrections, motion verbs, style blocks, and the script framing directive are API-level instructions that Video Agent interprets in English. Never translate these. 4. **Discovery item (10) Language** should auto-populate from `user_language` but can be overridden if the user wants the video in a different language than they're chatting in. 5. **Voice selection must match the video language.** Filter voices by `language` parameter and set `voice_settings.locale` on API calls. --- ## Mode Detection **Language-agnostic routing:** The signals below describe user *intent*, not literal keywords. Match intent regardless of input language. A user saying "ビデオを作って" (Japanese) is the same signal as "make a video about X." | Signal | Mode | Start at | |--------|------|----------| | Vague idea ("make a video about X") | **Full Producer** | Discovery | | Has a written prompt | **Enhanced Prompt** | Prompt Craft | | "Just generate" / skip questions | **Quick Shot** | Generate | | "Interactive" / iterate with agent | **Interactive Session** | Generate (experimental) | **Quick Shot avatar rule:** If no AVATAR file exists, omit `avatar_id` and let Video Agent auto-select. If an AVATAR file exists, use it — and Frame Check STILL RUNS. **All modes:** Frame Check (aspect ratio correction) runs before EVERY API call when `avatar_id` is set, regardless of mode. Quick Shot is not an excuse to skip framing checks. **Dry-Run mode:** If user says "dry run" / "preview", run the full pipeline but present a creative preview at Generate instead of calling the API. Default to Full Producer. Better to ask one smart question than generate a mediocre video. --- ## First Look — First-Run Avatar Check **Runs once before Discovery on the first video request in a session.** Check for any `AVATAR-*.md` files in the workspace root. - **Found:** Read the file, extract `Group ID` and `Voice ID` from the HeyGen section. Pre-load as defaults for Discovery. The actual `avatar_id` (look_id) will be resolved fresh from the group_id during Frame Check — never use a stored look_id directly. - **Not found:** The user (or agent) has no avatar yet. Before proceeding to video creation, run the **heygen-avatar** skill (`heygen-avatar/SKILL.md` in this repo) to create one. Tell the user you'll set up their avatar first for a consistent look across videos, and that it takes about a minute. Communicate in `user_language`. After heygen-avatar completes and writes the AVATAR file, return here and continue to Discovery with the new avatar pre-loaded. - **Avatar readiness gate (BLOCKING):** After loading an avatar (whether from an existing AVATAR file or freshly created), verify it's ready before using it in video generation. Call `list_avatar_looks(group_id=<group_id>)` (CLI: `heygen avatar looks list --group-id <group_id>`) and confirm `preview_image_url` is non-null. If null, poll every 10s up to 5 min. **Do NOT proceed to Discovery until this check passes.** Videos submitted with an unready avatar WILL fail silently. - **Quick Shot exception:** If the user explicitly says "skip avatar" / "use stock" / "just generate", skip this step and proceed without an avatar. --- ## Discovery Interview the user. Be conversational, skip anything already answered. **Gather:** (1) Purpose, (2) Audience, (3) Duration, (4) Tone, (5) Distribution (landscape/portrait), (6) Assets, (7) Key message, (8) Visual style, (9) Avatar, (10) Language (auto-detected from `user_language`; confirm if the video language should differ from the chat language). ### Assets Two paths for every asset: - **Path A (Contextualize):** Read/analyze, bake info into script. For reference material, auth-walled content. - **Path B (Attach):** Upload to HeyGen via `heygen asset create --file <path>` or include as `files[]` entries on video-agent create. For visuals the viewer should see. - **A+B (Both):** Summarize for script AND attach original. **Full routing matrix and upload examples** -> [references/asset-routing.md](references/asset-routing.md) **Key rules:** - HTML URLs cannot go in `files[]` (Video Agent rejects `text/html`). Web pages are always Path A. - Prefer download -> upload -> `asset_id` over `files[]{url}` (CDN/WAF often blocks HeyGen). - If a URL is inaccessible, tell the user. Never fabricate content from an inaccessible source. - **Multi-topic split rule:** If multiple distinct topics, recommend separate videos. ### Style Selection Two approaches — use one or combine both: **1. API Styles (`style_id`)** — Curated visual templates. Browse by tag, show 3-5 options with previews, let user pick. If a style has a fixed `aspect_ratio`, match orientation to it. When `style_id` is set, the prompt's Visual Style Block becomes optional. **2. Prompt Styles** — Full manual control via prompt text. See [references/prompt-styles.md](references/prompt-styles.md). ### Avatar **Full avatar discovery flow, creation APIs, voice selection** -> [references/avatar-discovery.md](references/avatar-discovery.md) **Decision flow:** 1. Ask: "Visible presenter or voice-over only?" 2. If voice-over -> no `avatar_id`, state in prompt. 3. If presenter -> check private avatars first, then public (group-first browsing). 4. **Always show preview images.** Never just list names. 5. Confirm voice preferences after avatar is settled. **Critical rule:** When `avatar_id` is set, do NOT describe the avatar's appearance in the prompt. Say "the selected presenter." This is the #1 cause of avatar mismatch. --- ## Pipeline: Script -> Prompt Craft -> Frame Check -> Generate -> Deliver After Discovery, the producer sub-skill handles the full pipeline. Read `heygen-video/SKILL.md` for detailed stage instructions. **Key rules that apply at every stage:** - **Language:** Script and narration in the video language (from Discovery item 10). Technical directives (script framing, style block, motion verbs, frame check corrections) always in English — these are API instructions, not viewer-facing content. - **Script:** Structure by type (demo, explainer, tutorial, pitch, announcement). Do NOT assign per-scene durations. Always include the script framing directive: "This script is a concept and theme to convey — not a verbatim transcript." - **Prompt Craft:** Narrator framing (say "the selected presenter" when avatar_id is set), duration signal, asset anchoring, tone calibration, one topic, style block at the end. - **Frame Check:** MANDATORY when avatar_id is set. See matrix below. - **Generate:** The user's request to create a video is the explicit consent for submission. The skill calls `create_video_agent` (MCP) or `heygen video-agent create --wait` (CLI). Run Frame Check before EVERY submission. Capture `session_id` immediately. Poll silently (or let `--wait` block). - **Deliver:** Report `video_page_url`, session URL, and duration accuracy. Log to `heygen-video-log.jsonl`. **Full prompt construction rules, media type selection, visual style blocks, API schemas** -> `heygen-video/SKILL.md` --- ## Frame Check **Runs automatically when `avatar_id` is set, before Generate. Appends correction notes to the Video Agent prompt. Does NOT generate images or create new looks.** ### Steps 1. **Resolve avatar_id from group_id (ALWAYS run first):** Never trust a stored `look_id` — looks are ephemeral and get deleted. Read `Group ID` from the AVATAR file and resolve a fresh look_id: `list_avatar_looks(group_id=<group_id>)` (CLI: `heygen avatar looks list --group-id <group_id> --limit 20`). Pick the look matching the target orientation. Use this resolved look_id as `avatar_id` for all subsequent steps. 2. **Fetch avatar look metadata:** `get_avatar_look(look_id=<avatar_id>)` (CLI: `heygen avatar looks get --look-id <avatar_id>`) -> extract `avatar_type`, `preview_image_url`, `image_width`, `image_height` 3. **Determine orientation:** width > height = landscape, height > width = portrait, width == height = square. Fetch fails = assume portrait. 4. **Determine background:** `photo_avatar` -> Video Agent handles environment. `studio_avatar` -> check if transparent/solid/empty. `video_avatar` -> always has background. 5. **Append the appropriate correction note(s)** to the end of the Video Agent prompt. That's it. No image generation, no new looks. ### Correction Matrix | avatar_type | Orientation Match? | Has Background? | Corrections | |---|---|---|---| | `photo_avatar` | matched | (n/a) | None | | `photo_avatar` | mismatched or square | (n/a) | Framing note | | `studio_avatar` | matched | Yes | None | | `studio_avatar` | matched | No | Background note | | `studio_avatar` | mismatched or square | Yes | Framing note | | `studio_avatar` | mismatched or square | No | Framing note + Background note | | `video_avatar` | matched | Yes | None | | `video_avatar` | mismatched or square | Yes | Framing note | ### Framing Note (append to prompt) For portrait/square avatar -> landscape video: ``` FRAMING NOTE: The selected avatar image is in {source} orientation but this video is landscape (16:9). Frame the presenter from the chest up, centered in the landscape canvas. Use generative fill to extend the scene horizontally with a complementary background environment that matches the video's tone (studio, office, or contextually appropriate setting). Do NOT add black bars or pillarboxing. The avatar should feel natural in the 16:9 frame. ``` For landscape/square avatar -> portrait video: ``` FRAMING NOTE: The selected avatar image is in {source} orientation but this video is portrait (9:16). Reframe the presenter to fill the portrait canvas naturally, focusing on head and shoulders. Use generative fill to extend vertically if needed. Do NOT add letterboxing. The avatar should fill the portrait frame comfortably. ``` ### Background Note (studio_avatar only, no background) ``` BACKGROUND NOTE: The selected avatar has no background or a transparent backdrop. Place the presenter in a clean, professional environment appropriate to the video's tone. For business/tech content: modern studio with soft lighting and subtle depth. For casual content: bright, minimal space with natural light. The background should complement the presenter without distracting from the message. ``` **Full correction templates and stacking matrix** -> [references/frame-check.md](references/frame-check.md) --- ## Best Practices - **Front-load the hook.** First 5s = 80% of retention. - **One idea per video.** Single-topic produces dramatically better results. - **Write for the ear.** If you wouldn't say it to a friend, rewrite it. **Known issues** -> [references/troubleshooting.md](references/troubleshooting.md)

path: CHANGELOG.md
content: # Changelog

## [2.2.1](https://github.com/heygen-com/skills/compare/v2.2.0...v2.2.1) (2026-04-27)


### Bug Fixes

* **install:** make avatar creation a first-class install step ([#71](https://github.com/heygen-com/skills/issues/71)) ([64ab640](https://github.com/heygen-com/skills/commit/64ab6404a3c2d0c7f32b55e2decf5de511c75f9e))

## [2.2.0](https://github.com/heygen-com/skills/compare/v2.1.2...v2.2.0) (2026-04-27)


### Features

* add Codex and Cursor plugin manifests ([#65](https://github.com/heygen-com/skills/issues/65)) ([df9458c](https://github.com/heygen-com/skills/commit/df9458cc3543eb0fbda4b32822886eaba6234380))
* INSTALL_FOR_AGENTS.md + 2-line paste-prompt install ([#68](https://github.com/heygen-com/skills/issues/68)) ([d58fa24](https://github.com/heygen-com/skills/commit/d58fa2411601cd97385c04f3bae9c0f087cbcc4a))
* route video generation through @heygen/openclaw-plugin-heygen when available ([#67](https://github.com/heygen-com/skills/issues/67)) ([a2526d0](https://github.com/heygen-com/skills/commit/a2526d0c5bdb91860882e0cbdadb326edfb41145))

## [2.1.2](https://github.com/heygen-com/skills/compare/v2.1.1...v2.1.2) (2026-04-17)


### Bug Fixes

* **frame-check:** specify AI Image tool for generative fill ([#62](https://github.com/heygen-com/skills/issues/62)) ([af77568](https://github.com/heygen-com/skills/commit/af77568e3f7c6fd76144869a05f8b20fb8639fec))

## [2.1.1](https://github.com/heygen-com/skills/compare/v2.1.0...v2.1.1) (2026-04-17)


### Bug Fixes

* **heygen-avatar:** agent-first default + prompt-based as primary path ([#55](https://github.com/heygen-com/skills/issues/55)) ([57c319b](https://github.com/heygen-com/skills/commit/57c319b656ffa8b88ea7ce6f85d49be30e27e927))
* **heygen-avatar:** Before You Start ran user-centric logic before Phase 0 ([#56](https://github.com/heygen-com/skills/issues/56)) ([0c1e9d3](https://github.com/heygen-com/skills/commit/0c1e9d38b96247fbd124966f85760e3b652ec18e))
* prevent batch-asking and fix agent onboarding flow ([#51](https://github.com/heygen-com/skills/issues/51)) ([e5e5db3](https://github.com/heygen-com/skills/commit/e5e5db358ada7429d1f1f2a51a232e4cfc5c763e))
* remove api-reference.md, enforce MCP xor CLI (no cross-lookup) ([#59](https://github.com/heygen-com/skills/issues/59)) ([75f1ee3](https://github.com/heygen-com/skills/commit/75f1ee3556ac051834a90914a6e2cf96ca6f46ef))
* silent mode detection, no CLI-broken narration ([#54](https://github.com/heygen-com/skills/issues/54)) ([ff7b6a3](https://github.com/heygen-com/skills/commit/ff7b6a32ffbd533b56f0aa8c040f78eef09500fd))
* **SKILL:** add UX rules against narrating skill internals, next-action, and transport choice ([#58](https://github.com/heygen-com/skills/issues/58)) ([3e8b06d](https://github.com/heygen-com/skills/commit/3e8b06df38538245596588909d4404b1eb850f1d))
* **SKILL:** HEYGEN_API_KEY presence → use CLI, short-circuit MCP ([#60](https://github.com/heygen-com/skills/issues/60)) ([808dd77](https://github.com/heygen-com/skills/commit/808dd776fc5c3f19b905f549a4a6c1ee46a2a656))

## [2.1.0](https://github.com/heygen-com/skills/compare/v2.0.3...v2.1.0) (2026-04-17)


### Features

* MCP-first API mode with CLI fallback ([#47](https://github.com/heygen-com/skills/issues/47)) ([4b052ae](https://github.com/heygen-com/skills/commit/4b052aee846589c0aefb861191fc6285d8c95c4e))


### Bug Fixes

* remove prompt injection triggers from README ([#44](https://github.com/heygen-com/skills/issues/44)) ([94981e0](https://github.com/heygen-com/skills/commit/94981e042429e2c6b4c3aebd72cf2dfbdcffd958))

## v1.3.7 (2026-04-13) — Auto-Proceed Fix

### Fixed
- **Video Agent review checkpoint** — The HeyGen v3 Video Agent API supports an `auto_proceed` flag in the request body. This skill documents passing `"auto_proceed": true` as a server-side API parameter that tells the HeyGen backend to skip its own internal review checkpoint — it is not granting the agent discretion to submit jobs unilaterally. The agent still requires the user to initiate a video generation request before any API call is made; no video jobs are submitted autonomously.
- **Batch submission throttle** — Capped parallel video submissions at 2–3 max to prevent queue congestion.
- Simplified polling status flow: `thinking → generating → completed` (no checkpoint approval step)

---

## v1.3.2 (2026-04-11) — Multi-Platform Distribution

### Added
- **Claude Code Marketplace** — Submission docs with plugin metadata, skill listing, and install instructions (`docs/claude-code-submission.md`)
- **Hermes Agent support** — `hermes` metadata block in root SKILL.md frontmatter (tags + category) and install guide (`docs/hermes-install.md`)
- **Manus support** — Import workflow docs (`docs/manus-install.md`)
- **NanoClaw container skill** — Compact 112-line SKILL.md at `platforms/nanoclaw/heygen/SKILL.md` covering avatar discovery, voice selection, script writing, v3 video generation, polling, and delivery
- **NanoClaw install guide** — `docs/nanoclaw-install.md`

### Fixed
- Synced `.claude-plugin/plugin.json` and `.claude-plugin/marketplace.json` version from 1.2.7 → 1.3.2

---

## v1.3.0 (2026-04-10) — i18n Support

### Added
- **Language Detection** — Skills detect user's language from input and communicate in that language
- **Language-aware voice selection** — Voice API calls filter by detected language; `voice_settings.locale` guidance added
- **Non-English script generation** — Scripts and narration generated in the video language
- **i18n eval suite** — Test scenarios across English, Japanese, Spanish, Korean with scoring rubric
- **Japanese example prompt** in prompt-craft reference
- **Language consistency criterion** (#11) in reviewer prompt

### Changed
- Mode Detection is now explicitly language-agnostic (semantic intent matching, not English keyword matching)
- User-facing messages converted from hardcoded English strings to semantic descriptions the LLM adapts to user's language
- Buddy voice construction pattern uses `{video_language}` instead of hardcoded "English"
- Buddy sign-off lines converted to semantic descriptions instead of English idioms
- Test video prompt (Phase 5) generates greeting in video language instead of hardcoded English

### Documentation
- Added `> Language note` callouts to motion-vocabulary.md and prompt-styles.md explaining English-only directives
- Updated api-reference.md with `voice_settings.locale` guidance and language filter examples
- All reference files document the content-language vs directive-language separation

---

## v1.2.7 (2026-04-09)

### Bug Fixes
- Synced version numbers across all files (SKILL.md frontmatter, User-Agent headers, plugin.json, marketplace.json) to match VERSION file
- Fixed Quick Shot avatar_id rule in heygen-video to use AVATAR file when available instead of always omitting
- Completed Frame Check correction matrix with Aspect Ratio column and ratio-fix corrections (F, G) across root SKILL.md and frame-check.md
- Fixed frame-check.md correction stacking matrix: removed stale 4-column header, corrected intro sentence (photo_avatar never gets background correction C)
- Replaced macOS-incompatible `readlink -f` in heygen-video preamble with POSIX-compatible path resolution

### Architecture
- Trimmed root SKILL.md from 399 to ~215 lines by extracting duplicated Script, Prompt Craft, and Generate content into the producer sub-skill where it belongs
- Fixed stale path reference: `identity/SKILL.md` -> `heygen-avatar/SKILL.md`
- Registered buddy-to-avatar skill in marketplace.json

### Documentation
- Added buddy-to-avatar to README "What's Inside" section

## v1.1.0 (2026-04-06)

### heygen-video
- Prompt-only Frame Check architecture (no external image generation, preserves face identity)
- submit-video.sh wrapper enforces aspect ratio checks before every API call
- Phase naming overhaul: action verbs replace numbered phases (Discovery, Script, Prompt Craft, Frame Check, Generate, Deliver)
- Style-adaptive Phase 3.5: 3D, animated, and photorealistic avatars get matching fill directives
- ATO lane carving: distinct tool descriptions for agent discoverability vs built-in video_generate
- Version check system with cache TTLs and snooze backoff
- Inline MP4 delivery (downloads video, sends as media attachment)
- Hard gates at all user decision points

### heygen-avatar
- Voice Design endpoint (POST /v3/voices) with semantic search, seed pagination
- Reference photo nudge on first-time avatar creation
- Inline audio previews for voice selection
- Hard gates: voice selection and avatar approval require explicit user confirmation
- UX Rules: interactive at checkpoints, silent everywhere else
- Moved into heygen-stack monorepo

### Infrastructure
- submit-video.sh: auto-validates avatar dimensions, appends FRAMING NOTE if mismatch detected
- update-check script moved from bin/ to scripts/
- Branch protection: 1 approval required, CODEOWNERS enforced
- README trimmed to essentials (Quick Start, What's Inside, How It Works)

## v1.0.0 (2026-04-01)

Initial release. Five-phase video production pipeline with avatar discovery, prompt engineering, aspect ratio corrections, and HeyGen Video Agent API integration. 22 eval rounds, 80+ test videos generated.


path: CLAUDE.md
content: # CLAUDE.md — HeyGen Skills

## What This Is

The HeyGen Skills. Two skills that chain together: **heygen-avatar** (identity → avatar → voice) and **heygen-video** (idea → script → video). SKILL.md at root routes between them.

## Architecture

```
heygen-skills/
├── SKILL.md                    # Router: detects intent, dispatches to sub-skill
├── CLAUDE.md                   # This file. Structure, rules, conventions.
├── INSTALL.md                  # Installation instructions
├── README.md                   # Public-facing description
├── CONTRIBUTING.md             # PR workflow
├── LICENSE
├── heygen-avatar/
│   └── SKILL.md                # Avatar creation workflow (identity → avatar → voice → AVATAR file)
├── heygen-video/
│   └── SKILL.md                # Video production workflow (7-stage pipeline)
├── references/                 # Shared. Loaded on-demand by phase (NOT every turn)
│   ├── avatar-discovery.md     # Discovery: avatar lookup, voice selection, curl examples
│   ├── asset-routing.md        # Discovery: asset classification engine, upload flows
│   ├── prompt-styles.md        # Prompt Craft: 6 prompt style templates
│   ├── motion-vocabulary.md    # Prompt Craft: camera/transition vocabulary
│   ├── prompt-craft.md         # Prompt Craft: prompt construction deep-dive
│   ├── official-prompt-guide.md# Prompt Craft: HeyGen's own prompt research
│   ├── frame-check.md          # Frame Check: aspect ratio correction prompts
│   ├── troubleshooting.md      # Known issues, workarounds, duration variance
│   └── reviewer-prompt.md      # Deliver: self-evaluation rubric
└── evals/                      # Dev-only test infrastructure (not shipped to users)
    ├── eval-runner-prompt.md   # Instructions for eval subagent
    ├── autoresearch-loop.md    # Loop methodology docs
    └── round-N-scenarios.md    # Per-round test scenarios
```

## The 300-Line Rule

Each SKILL.md must stay under 300 lines. Skill files are injected into EVERY prompt turn.

**What stays in SKILL.md:**
- Frontmatter (name, description, triggers, env requirements)
- Stage flow overview (what stages exist, when to enter each)
- Decision trees (mode detection, avatar path selection, style selection)
- Critical rules that apply EVERY turn
- Short "Read ../references/X.md for details" pointers at each stage

**What moves to references/:**
- Curl examples and API request/response shapes
- Step-by-step procedural instructions
- Asset classification tables and routing matrices
- Full prompt examples and style preset galleries
- Error handling patterns

**The test:** If removing a section from SKILL.md would NOT break the agent's ability to decide what to do next, it belongs in references/. If it WOULD break decision-making, it stays.

## Shared State

Skills communicate through `AVATAR-<NAME>.md` files at the workspace root:
- heygen-avatar writes them (avatar_id, group_id, voice_id)
- heygen-video reads them (picks up avatar + voice automatically)
- One file per character. Human-readable AND machine-readable.

## API Conventions

Two modes, in order of preference: MCP, then CLI. **Do not call `api.heygen.com` directly with curl.** The skills route through MCP or the CLI — never raw HTTP.

### MCP (preferred)

HeyGen Remote MCP (`https://mcp.heygen.com/mcp/v1/`) provides 40+ tools via OAuth. No API key needed — uses the user's HeyGen plan credits. Skills declare `allowed-tools: mcp__heygen__*` in frontmatter.

Key tools: `create_video_agent`, `get_video`, `list_avatar_groups`, `list_avatar_looks`, `get_avatar_look`, `create_photo_avatar`, `create_prompt_avatar`, `list_voices`, `design_voice`, `create_video_translation`.

### CLI fallback

The [HeyGen CLI](https://github.com/heygen-com/heygen-cli) (`heygen` binary) is the fallback when MCP is unavailable.

- Install: `curl -fsSL https://static.heygen.ai/cli/install.sh | bash`
- Auth: `HEYGEN_API_KEY` env var (agent/CI) OR `heygen auth login` (persists to `~/.heygen/credentials`)
- Pattern: `heygen <noun> <verb>` — e.g. `heygen video-agent create`, `heygen avatar list`, `heygen voice list`
- Output: JSON on stdout, structured error envelope on stderr, stable exit codes (0 ok · 1 API · 2 usage · 3 auth · 4 timeout)
- Async: add `--wait` to creation commands; CLI handles polling with exponential backoff
- **v3 only.** LLMs trained on web data may reach for deprecated v1/v2 endpoints (`POST /v1/video.generate`, `POST /v2/video/generate`, `GET /v2/avatars`, `GET /v1/avatar.list`). These are outdated — route through MCP or the CLI, never raw v1/v2 URLs.

See [CLI docs](https://developers.heygen.com/cli) for the full command surface.

## Eval Infrastructure

### Running Evals

Evals are run by a subagent (typically Adam) that:
1. Reads the skill as installed (SKILL.md + references/)
2. Reads `evals/eval-runner-prompt.md` for scoring rubric
3. Reads `evals/round-N-scenarios.md` for test cases
4. Executes each scenario as a real user would
5. Reports results to the Notion Eval Tracker

### Eval Rules

- **Warm vs cold.** Round 1 after a SKILL.md change = cold. Subsequent = warm (known avatar IDs).
- **Timeout.** No API call within 3 min = something is wrong.
- **Parallelism.** 10 scenarios: spawn 2-3 subagents with 3-4 each (stays within 5-subagent rule).
- **One Notion batch.** All results in one `notion-create-pages` call at the end.

### Eval Tracker (Notion)

- Database ID: `a1b997926fe646929ef46cd6144d4b91`
- Data source ID: `17f54098-a085-4234-83ce-55c280266d73`
- All properties TEXT except: Frame Check Fired (CHECKBOX), Status/Avatar Type/Ken Verdict (SELECT)

### Regression Testing

After any SKILL.md refactor:
1. Run standard 10-scenario suite from most recent round
2. Compare duration accuracy, score, pass rate vs previous round
3. Regression >10% avg score or >15% duration accuracy = revert
4. Frame Check must fire on same scenarios as before

## Key Decisions (Do Not Revisit Without Data)

Validated across 18 rounds of testing (80+ videos):

1. **Video Agent as primary command.** `heygen video-agent create`, not `heygen video create`.
2. **avatar_id over prompt description.** 97.6% duration accuracy vs 77-82% prompt-only.
3. **When avatar_id is set, omit appearance description from prompt.** Say "the selected presenter" instead.
4. **Script-as-prompt approach.** Full scene-labeled script pasted into prompt.
5. **Trust Video Agent for duration pacing.** No padding multipliers.
6. **Frame Check appends FRAMING NOTE / BACKGROUND NOTE to prompt — no image generation.**
7. **Dry-run before API.** Always offer.
8. **Quick Shot mode: omit avatar_id, let Video Agent auto-select.**
9. **video_avatar type has a known backend bug.** Document in troubleshooting.
10. **Prompt-only Frame Check.** Corrections append text notes (FRAMING NOTE / BACKGROUND NOTE) to the Video Agent prompt. Video Agent handles framing internally. No image generation, no look creation, no asset uploads.


path: CONTRIBUTING.md
content: # Contributing to HeyGen Skills

## Git Workflow

All changes go through pull requests. No direct pushes to `main`.

### For every change:

```bash
# 1. Create a branch from master
git checkout master && git pull
git checkout -b <type>/<short-description>
# e.g. feat/multi-language-support, fix/duration-padding, refactor/avatar-flow

# 2. Make changes, commit with clear messages
git add -A
git commit -m "Short summary of what changed

- Bullet points explaining WHY, not just what
- Reference any eval results or test outputs
- Note any breaking changes to the skill interface"

# 3. Push and create PR
git push -u origin <branch-name>
gh pr create --title "Short summary" --body "$(cat <<'EOF'
## What

[One paragraph: what this PR does]

## Why

[One paragraph: why this change is needed]

## Changes

- [Bullet list of specific changes]

## Testing

- [ ] Dry-run tested (paste output or describe scenario)
- [ ] Full generation tested (video_id if applicable)
- [ ] SKILL.md reads clean end-to-end
- [ ] No spec-sheet language leaked into user-facing output

## Breaking changes

[None / describe what breaks]
EOF
)"
```

### Branch naming

| Prefix | Use for |
|--------|---------|
| `feat/` | New capability (new mode, new phase, asset handling) |
| `fix/` | Bug fix (duration math, API error handling) |
| `refactor/` | Internal cleanup (no behavior change) |
| `docs/` | README, CONTRIBUTING, eval docs only |
| `eval/` | New eval scenarios or test infrastructure |

### PR review checklist

Before merging, confirm:

1. **One pipeline** — dry-run and full generation share identical logic through prompt construction. No forked code paths.
2. **Creative, not clinical** — user-facing output reads like a pitch, not a form submission. No timestamps, no Settings blocks, no padding math.
3. **SKILL.md is the source of truth** — if behavior changed, SKILL.md reflects it. An agent reading only SKILL.md can execute the full skill correctly.
4. **Evals updated** — if the change affects prompt quality or output format, add or update scenarios in `evals/`.
5. **Commit messages explain why** — not just "updated SKILL.md".

### After merge

```bash
git checkout master && git pull
git branch -d <branch-name>
```

**NEVER reuse a merged or closed branch.** New work = new branch off master. Don't push additional commits to a branch whose PR was already merged or closed.

### Eve's workflow (for autonomous changes)

When Eve updates the skill without Ken online:
1. Create branch, commit, push, open PR
2. Post PR link to Ken on Telegram
3. Wait for review before merging
4. Never push directly to master

---

## How We Test: The Autoresearch Loop

This skill was built through 20 rounds of automated evaluation, producing 80+ videos. The methodology is inspired by Karpathy's autoresearch concept: define scenarios, run them blind, classify failures, fix the skill, repeat.

### The Loop

```
┌──────────────────────────────────────────────────────┐
│  1. DESIGN — Write 10 test scenarios                 │
│     Each has: user prompt, expected behavior,        │
│     avatar config, target duration, what to watch    │
├──────────────────────────────────────────────────────┤
│  2. EXECUTE — Fresh agent runs all 10 blind          │
│     No prior context. Only reads SKILL.md.           │
│     Logs: video_id, payload, duration, corrections   │
├──────────────────────────────────────────────────────┤
│  3. EVALUATE — Score each scenario 1-10              │
│     Write results to tracking database (Notion)      │
│     Classify issues: P0 (broken) → P3 (cosmetic)    │
├──────────────────────────────────────────────────────┤
│  4. FIX — Address P0/P1 findings in SKILL.md         │
│     Open PR with findings → fixes mapping            │
│     Human reviews videos + diffs before merge        │
├──────────────────────────────────────────────────────┤
│  5. REPEAT — Next round targets regressions +        │
│     new edge cases. Each round builds on the last.   │
└──────────────────────────────────────────────────────┘
```

### Why This Works

**The tester agent reads only SKILL.md.** No tribal knowledge, no chat history, no "you know what I mean." If the skill file doesn't say it clearly, the agent gets it wrong. This surfaces documentation gaps that human review misses.

**Scenarios escalate.** Early rounds test happy paths ("make a 30s product demo"). Later rounds push boundaries: square avatars, style_id combinations, 90-second long-form, Quick Shot mode, prompt-based framing corrections.

**Fixes are surgical.** Each round produces a branch, a PR, and a clear mapping from finding to fix. No rewrites unless the architecture is wrong.

### What We Learned (R1–R20)

| Finding | Round | Impact |
|---------|-------|--------|
| SKILL.md at 57KB consumed ~15K tokens/turn | R10 | Refactored to 259 lines (78% reduction) |
| avatar_id + appearance text in prompt conflict | R7 | Narrator framing rule: omit appearance when avatar_id set |
| Frame Check corrections not appended to prompt | R3 | Added explicit correction note templates |
| Timestamps per scene make delivery robotic | R8 | Switched to natural flow + tone description |
| 365% duration overshoot on short videos | R12 | Script framing directive added |
| Square (1:1) avatars letterboxed with black bars | R18 | Square detection + correction blocks D/E |
| External image gen in Frame Check degraded face identity | R20 | Reverted to prompt-only approach — Video Agent handles framing internally |

### Running Your Own Evals

The `evals/` directory (gitignored, not shipped) contains our scenario files and runner prompt. To run your own:

1. Create `evals/round-N-scenarios.md` with 10 scenarios
2. Each scenario needs: user prompt, avatar config, target duration, orientation, what to watch for
3. Have a fresh agent (no prior context) read SKILL.md and execute all 10
4. Score results, classify issues, fix SKILL.md, open PR
5. Repeat until the round scores 9+/10 average

The concept matters more than the tooling. Any agent framework can run this loop. The key insight: **the skill file is the product, and the eval loop is the compiler.**


path: INSTALL.md
content: # Install HeyGen Skills

Grab an [API key](https://app.heygen.com/api) and set it in your shell. If you're already on a HeyGen plan with MCP connected to your agent, you can skip the key — MCP will be used automatically.

## Option 1 — ClawHub (recommended)

```bash
clawhub install heygen-skills
```

ClawHub installs to your agent's default skills directory automatically.

## Option 2 — Git clone

Clone into your agent's skills directory:

**OpenClaw** (default: `~/.openclaw/skills/heygen-skills`, custom installs may differ — check your config):
```bash
git clone https://github.com/heygen-com/skills.git ~/.openclaw/skills/heygen-skills
```

**Claude Code** (default: `~/.claude/skills/heygen-skills`):
```bash
git clone https://github.com/heygen-com/skills.git ~/.claude/skills/heygen-skills
```

> Not sure where your skills directory is? Ask your agent: *"Where is your skills directory?"*

## Auth

Two auth modes with explicit priority:

| Priority | Mode | Trigger | Billing |
|----------|------|---------|---------|
| 1 | **CLI (API key)** | `HEYGEN_API_KEY` is set | Direct API usage (separately billed) |
| 2 | **MCP (OAuth)** | MCP tools visible AND no API key | HeyGen plan credits (existing subscription) |
| 3 | **CLI (fallback)** | `heygen auth login` session | Direct API usage |

**CLI with API key (recommended for agents):**
```bash
curl -fsSL https://static.heygen.ai/cli/install.sh | bash
export HEYGEN_API_KEY=<your-key>
heygen --version        # verify binary is on PATH
heygen auth status      # verify auth
```

> If `HEYGEN_API_KEY` is set, the skills use the CLI. This is the most predictable setup for agent workflows.

**MCP (zero-setup if on a HeyGen plan):** connect HeyGen's remote MCP server to your agent — OAuth handles auth, calls use your existing plan credits. See README for agent-specific setup.

## First Run

Paste this prompt to your agent — it will find the right paths automatically:

> Install the HeyGen Skills from https://github.com/heygen-com/skills.git — clone it into your skills directory (find it with your config or ask if unsure). Install the HeyGen CLI via `curl -fsSL https://static.heygen.ai/cli/install.sh | bash` and export HEYGEN_API_KEY=\<your-key\> (get one at https://app.heygen.com/api). Or, if you're on a HeyGen plan and already have MCP connected to your agent, skip the key step — MCP will be used automatically. Then use the heygen-avatar skill to create an avatar for me, and heygen-video to make a 30-60 second intro video, casual tone.


path: INSTALL_FOR_AGENTS.md
content: # HeyGen Skills — Installation Guide for AI Agents

Read this entire file, then follow the steps. Ask the user for API keys when needed.
Target: ~5 minutes to a fully working HeyGen integration.

This file is the agent-facing companion to [`INSTALL.md`](./INSTALL.md) (human-facing).
Where they overlap, this file is canonical for agent-driven installs.

## Step 0: If you are not Claude Code

Read [`CLAUDE.md`](./CLAUDE.md) at the repo root first. It describes the
runtime contract for these skills (mode detection, hard rules,
transport-only-once). Claude Code reads it automatically; other agents
should fetch it explicitly.

If you fetched this file by URL without cloning yet, the companion files
live at:

- `https://raw.githubusercontent.com/heygen-com/skills/master/CLAUDE.md` — runtime contract for the skills
- `https://raw.githubusercontent.com/heygen-com/skills/master/SKILL.md` — top-level skill (mode detection ladder, hard rules)
- `https://raw.githubusercontent.com/heygen-com/skills/master/heygen-avatar/SKILL.md` — avatar creation sub-skill
- `https://raw.githubusercontent.com/heygen-com/skills/master/heygen-video/SKILL.md` — video generation sub-skill
- `https://raw.githubusercontent.com/heygen-com/skills/master/INSTALL.md` — human-facing install doc

## Step 1: Detect the agent host and pick the install path

Detect which agent is running before cloning. Each host expects skills at a
different path. If you are not sure, ask the user "which AI coding agent are
you running this from?"

| Agent host    | Default install path                          |
|---------------|-----------------------------------------------|
| Claude Code   | `~/.claude/skills/heygen-skills`              |
| OpenClaw      | `~/.openclaw/skills/heygen-skills`            |
| Codex         | `~/.codex/skills/heygen-skills`               |
| Cursor        | `~/.cursor/skills/heygen-skills`              |
| Hermes        | `~/.hermes/skills/heygen-skills`              |
| Other         | Whatever path the host loads skills from. Ask the user. |

OpenClaw users running a workspace-scoped install may have skills under
`~/.openclaw/workspace/skills/heygen-skills` instead — check the value of the
host's `--dir` / `workdir` config. The default above is canonical for
non-workspace installs and matches [`INSTALL.md`](./INSTALL.md).

```bash
# Replace <install-path> with the row from the table above:
git clone --single-branch --depth 1 \
  https://github.com/heygen-com/skills.git \
  <install-path>
```

For OpenClaw users, the **fastest install path is ClawHub** — it short-circuits
Steps 1, 3, and 4 below (clones to the right path, registers with the host, and
sets up the install metadata in one command):

```bash
clawhub install heygen-skills
```

After ClawHub install, jump straight to **Step 2** (API key) and then
**Step 5** (avatar creation).

## Step 2: Get the user's HeyGen API key (or detect MCP)

**First, detect whether the user already has the HeyGen MCP server connected.**
If `mcp__heygen__*` tools are visible in the toolset, MCP is the path of least
resistance — OAuth, no key handling, consumes the user's HeyGen plan credits.

If MCP is detected and the user is happy with it, **skip to Step 5 (avatar creation)**.
But before you do, warn them:

> If you set `HEYGEN_API_KEY` later for any reason, the skill will short-circuit
> MCP detection (per the mode-detection ladder in `SKILL.md`) and use the CLI /
> direct-API route instead. MCP plan credits won't be touched. To switch back to
> MCP, unset `HEYGEN_API_KEY`.

**If MCP is not connected**, ask the user for their HeyGen API key. They get
it from [app.heygen.com/api](https://app.heygen.com/api) (Settings → API → New
Key). Tell them: *the key is shown once, copy it before closing the modal.*

The HeyGen API is currently pay-as-you-go in credits — no free tier. Avatar V
costs roughly 6 credits per minute of generated video. Make sure the user has
credits or is on a paid plan before proceeding. Pricing changes; if the user
asks for current rates, point them at
[help.heygen.com/api-pricing](https://help.heygen.com/en/articles/10060327-heygen-api-pricing-explained).

## Step 3: Save the API key in the standard location

The key needs to be available to whichever transport the user picks in Step 4.
The safe default is to set it as an environment variable in the user's shell
profile.

```bash
# In ~/.zshrc, ~/.bashrc, or wherever the user's shell loads env vars:
export HEYGEN_API_KEY=hg_...
```

Then ask the user to either restart their shell or `source` the file. The
agent's process inherits the parent shell's env — if the agent runs in a
separate process from the user's terminal, they'll need to restart the agent
host, not just re-source the shell.

If the user prefers a project-local key, drop it in `.env` and tell the user
to never commit it. The `.env.example` file shows the expected variable name.

For the OpenClaw plugin path (Step 4 Option A), the key is read from the same
`HEYGEN_API_KEY` env var. The plugin does not require a separate config step.

## Step 4: Pick a transport

These skills route the actual HeyGen API call through one of three transports.
The skill auto-detects which transport is available at runtime via the
mode-detection ladder in [`SKILL.md`](./SKILL.md):

> 1. **OpenClaw plugin** if `video_generate` exposes `heygen/video_agent_v3`
> 2. **CLI (API-key override)** if `HEYGEN_API_KEY` is set AND `heygen --version` exits 0
> 3. **MCP** if no API key set AND `mcp__heygen__*` tools visible
> 4. **CLI (fallback)** if MCP unavailable AND `heygen --version` exits 0

The critical rule: **setting `HEYGEN_API_KEY` short-circuits MCP detection**.
If the user wants MCP-credit billing, do not set the key.

Pick a transport based on the user's host and preferences:

### Option A: OpenClaw plugin (preferred for OpenClaw users)

Ships HeyGen as a first-class provider for OpenClaw's `video_generate` tool.
Auth, polling, and error handling are native. Cleanest integration.

```bash
openclaw plugins install openclaw-plugin-heygen
```

The plugin reads `HEYGEN_API_KEY` from the environment (set in Step 3).
Restart the gateway to pick up the new provider registration:

```bash
openclaw gateway restart
```

Verify the plugin loaded:

```bash
openclaw plugins list | grep heygen
```

The skill detects the plugin by checking whether `video_generate` exposes
`heygen/video_agent_v3` as a model. When detected, the `heygen-video`
sub-skill routes the final video-generate call through `video_generate(...)`
instead of spawning a CLI process.

### Option B: HeyGen CLI (works with any agent that can shell out)

```bash
curl -fsSL https://static.heygen.ai/cli/install.sh | bash
```

Then sign in:

```bash
heygen auth login
```

The CLI persists the key to `~/.heygen/credentials`. The skill detects the CLI
via `heygen --version`.

### Option C: HeyGen MCP server (Claude Desktop, Claude Code with MCP, OpenClaw with MCP)

If MCP is already wired up, the skill detects `mcp__heygen__*` tools and uses
them. No CLI install needed. Auth is OAuth; consumes the user's HeyGen plan
credits (not API credits).

To wire MCP from scratch, follow your agent's MCP setup docs and point it at
`https://mcp.heygen.com/mcp/v1/`. We can not configure that from inside this
skill. See [`INSTALL.md`](./INSTALL.md) for example configs.

## Step 5: Give the agent a face (canonical install outcome)

This is the step the install is actually for. Until now we've installed
files and wired auth. Now we make the thing the user came here for: an
avatar the agent can use to present videos.

**Default subject is the agent, not the user.** The `heygen-avatar`
sub-skill is built around the agent getting a face by default. Route to a
user-avatar only on explicit "my avatar" / "me" / "my photo" language. When
in doubt, make the agent's avatar.

### If you are running in an OpenClaw workspace with `SOUL.md` and `IDENTITY.md`

This is the canonical path. The agent has documented identity files; the
skill reads them and designs a presenter that matches.

Read [`heygen-avatar/SKILL.md`](./heygen-avatar/SKILL.md) and follow Phase 0.
The skill will:

1. Read `SOUL.md` and `IDENTITY.md` from the workspace root.
2. Ask one or two clarifying questions about design direction (not a
   batch form — walk the phases in order, one or two questions at a time).
3. Generate the avatar via the Avatar V pipeline (prompt-based by default;
   photo opt-in only for real-person digital twins).
4. Save `AVATAR-<AGENT-NAME>.md` at the workspace root for future reuse.
5. Return `avatar_id` + `voice_id` for use in Step 7 (defaults).

On the happy path, this step ends with a new file like `AVATAR-EVE.md`,
`AVATAR-ADAM.md`, or `AVATAR-CLEO.md` at the workspace root. That file is
the persistent identity — every future video reuses it automatically. Note
that the heygen-avatar skill has a Phase 2 STOP gate before generation; if
the user aborts there, no file is written and no credits are spent. That's
the correct behavior — it's a confirmation gate, not a bug. Resume by
re-invoking the sub-skill.

### If you are running outside an OpenClaw workspace (no `SOUL.md`)

Claude Code, Codex, Cursor, and Hermes don't have workspace identity files.
The avatar still gets created, but the skill asks the user for the design
direction directly instead of reading from `SOUL.md`.

Same entry point: read [`heygen-avatar/SKILL.md`](./heygen-avatar/SKILL.md)
and follow Phase 0. The skill detects the missing `SOUL.md` and switches
to Phase 1 conversational onboarding — it asks the user about appearance,
voice, and presenter persona one or two traits at a time, not as a single
batch prompt.

### Skip conditions (rare)

Skip Step 5 only if:

- The user has explicitly said "I already have an avatar, just make a video"
  (they have an existing `avatar_id` / `voice_id` they want to reuse).
- The install is purely scoped to video generation with stock avatars (the
  user picks from HeyGen's catalog per-call).

In either case, jump to Step 6. Otherwise, the install is incomplete
without this step.

## Step 6: Verify the install (opt-in)

Ask the user: **"Want to run a 5-second smoke test? It generates a real
video, costs roughly half a credit, and confirms the integration works
end-to-end."**

If yes, branch on whether Step 5 ran:

**If Step 5 created an avatar:**

```
Use heygen-video to generate a 5-second test clip with the avatar from
AVATAR-<NAME>.md saying "HeyGen install working, ready to ship." Save
the file locally and tell me the path.
```

**If Step 5 was skipped (user has an existing `avatar_id` they want to reuse,
or scoped install to stock avatars):**

```
Use heygen-video to generate a 5-second test clip with avatar_id
<the user's avatar_id> and voice_id <the user's voice_id> saying
"HeyGen install working, ready to ship." Save the file locally and tell
me the path.
```

Expected outcome: a `.mp4` file roughly 1-3 MB, 5 seconds long, with the
avatar speaking the test line.

If the user declines, skip to Step 7. The skill works either way; the smoke
test just removes uncertainty about whether everything is wired correctly.

If the smoke test fails, the most common causes (in order):

1. **`HEYGEN_API_KEY` not in current shell.** Re-source the shell profile or
   restart the terminal / agent host.
2. **No credits on the account.** Tell the user, then point them at
   [app.heygen.com/billing](https://app.heygen.com/billing).
3. **Transport not detected.** Run `heygen --version` (Option B) or check
   `openclaw plugins list` (Option A) to confirm the path exists.
4. **`waiting_for_input` state from the Video Agent.** The skill set
   `mode` incorrectly — see the heygen-video sub-skill's review-checkpoint
   handler. Re-read the sub-skill SKILL.md.

## Step 7: Set agent-wide defaults

This step only applies if **Step 5 ran** (the user has a new
`AVATAR-<NAME>.md`) OR if **the user already has an `avatar_id` / `voice_id`**
they want to reuse on every call. If neither, skip to Step 8.

When it applies, save the ids as defaults so the user doesn't repeat them
per-call.

For the **OpenClaw plugin path** (Option A), use `openclaw config set`:

```bash
openclaw config set plugins.entries.heygen.config.defaultAvatarId "<avatar_id>"
openclaw config set plugins.entries.heygen.config.defaultVoiceId  "<voice_id>"
openclaw config set plugins.entries.heygen.config.defaultStyleId  "<style_id>"
```

For the **CLI path** (Option B), defaults live in `~/.heygen/config` — the
CLI will prompt on first use, or you can run `heygen config set` directly.

For the **MCP path** (Option C), there are no per-skill defaults; the agent
passes avatar / voice ids per call. If Step 5 ran, the `AVATAR-<NAME>.md`
file is the source of truth and the agent reads it on each video
generation. If Step 5 was skipped, the user provides ids per call directly.

## Step 8: Make HeyGen the default video provider (OpenClaw plugin path only)

If the user wants `video_generate(...)` to default to HeyGen when no model is
specified:

```bash
openclaw config set agents.defaults.videoGenerationModel.primary "heygen/video_agent_v3"
```

This is purely an OpenClaw concern and does not affect Claude Code, Codex, or
Cursor users.

## Step 9: Done

The skills now have everything they need: a transport, an authenticated
account, an avatar identity, and (optionally) defaults for repeated use.
Tell the user:

> HeyGen Skills are installed. Your agent now has a face: `AVATAR-<NAME>.md`.
> Try:
> - "Make a 30-second video of yourself introducing what we're working on this week"
> - "Send a video update to the team about today's progress"
> - "Generate a 60-second product walkthrough using my avatar"

The skill handles avatar resolution, prompt engineering, aspect ratio
correction, voice selection, and Frame Check automatically. Give it a topic,
let it do the rest.

## Upgrade

```bash
cd <install-path>/heygen-skills && git pull origin master
```

If the install was via ClawHub:

```bash
clawhub update heygen-skills
```

Re-read [`SKILL.md`](./SKILL.md) after the upgrade if the version bumped — the
mode detection ladder occasionally adds new transports (e.g. when MCP support
shipped, when the OpenClaw plugin shipped).

## Troubleshooting

**The agent says HEYGEN_API_KEY is not set, but the user already exported
it.** The export only applies to the shell that ran it. If the agent is in a
separate process (most agents are), the export needs to be in `~/.zshrc` or
`~/.bashrc` and either re-sourced or used in a fresh shell.

**The CLI works in the terminal but the agent says it can't find it.** The
agent's PATH is different from the user's interactive shell. Tell the user
to add `~/.local/bin` (or wherever the CLI lands) to a PATH that the agent
inherits.

**`waiting_for_input` from the Video Agent.** The skill is calling the Video
Agent in chat mode by accident. Re-read the heygen-video sub-skill — it
should always pass `mode: "generate"` for one-shot video creation. If you
patched the sub-skill, you may have introduced this regression.

**MCP tools listed but the skill is using the CLI / plugin instead.** The
skill follows the mode-detection ladder in `SKILL.md`: plugin → CLI
(API-key override) → MCP → CLI (fallback). **`HEYGEN_API_KEY` being set
short-circuits MCP detection.** If the user wants MCP to be the chosen
transport, unset the env var (`unset HEYGEN_API_KEY`) and re-detect. If the
plugin is also installed, uninstall it (`openclaw plugins uninstall
openclaw-plugin-heygen`) so MCP wins detection.

## What this skill does NOT do

- It does not handle account creation. The user must already have a HeyGen
  account with API access.
- It does not bill or upgrade the user's HeyGen plan. If they run out of
  credits, point them at [app.heygen.com/billing](https://app.heygen.com/billing).
- It does not store or transmit the API key anywhere outside the local agent
  environment. The key stays in the user's shell or in the agent host's
  config; the skill never logs it.


path: README.md
content: # HeyGen Skills

AI agent skills for creating avatar videos. Your agent gets a face, a voice, and the ability to send video like a message.

Works with Claude Code, OpenClaw, Codex, Cursor, and other AI coding agents.

```
"Bring yourself to life — create your own avatar and make a 30-second intro video of yourself. Use heygen-avatar and heygen-video, ask me anything before you start."
→ reads your agent's identity files → asks only what's missing → builds the agent's avatar → picks the best style → generates the video → delivers the share link
```

## Install

**Paste this into your agent.** It does the rest — clones the repo to the right path, asks for your HeyGen API key, picks the best transport, runs a verify test, and ends with a working video.

```
Read https://raw.githubusercontent.com/heygen-com/skills/master/INSTALL_FOR_AGENTS.md and follow it.
Ask me for any API keys you need.
```

That's it. The agent fetches [INSTALL_FOR_AGENTS.md](./INSTALL_FOR_AGENTS.md) and walks the rest of the install. Same prompt forever — the install spec lives in the repo, not in your clipboard.

Want to install manually instead? Follow the steps below.

### Step 1 — Clone into your skills directory

Detect which agent you are and clone to the right path:

| Agent | Install path |
|-------|-------------|
| **Claude Code** | `~/.claude/skills/heygen-skills` |
| **OpenClaw** | `~/.openclaw/workspace/skills/heygen-skills` |
| **ClawHub** | Run `clawhub install heygen-skills` and skip to Step 2 |
| **Other** | Clone anywhere your agent loads skills from |

```bash
git clone --single-branch --depth 1 https://github.com/heygen-com/skills.git <install-path>/heygen-skills
```

### Step 2 — Get your HeyGen API key

1. Go to **[app.heygen.com/api](https://app.heygen.com/api)** (Settings → API)
2. Generate a new API key
3. Save it somewhere safe — you can't view it again after the modal closes

### Step 3 — Install the HeyGen CLI

One-line install (macOS / Linux):

```bash
curl -fsSL https://static.heygen.ai/cli/install.sh | bash
```

Then set your API key:

```bash
export HEYGEN_API_KEY=<your-key>
```

That's ephemeral (current shell only). To persist across sessions, add `export HEYGEN_API_KEY=<your-key>` to your shell profile (`~/.zshrc`, `~/.bashrc`, or equivalent).

Verify:

```bash
heygen --version
heygen auth status
```

The [HeyGen CLI](https://github.com/heygen-com/heygen-cli) is a single static binary. No runtime deps.

### Alternative: MCP (OAuth, no API key)

If you prefer OAuth and already have a HeyGen plan with credits, connect the remote MCP server instead of setting an API key. The skills will auto-detect MCP when no `HEYGEN_API_KEY` is set.

Claude Code:
```bash
claude mcp add --transport http heygen https://mcp.heygen.com/mcp/v1/
```

OpenClaw: add to `~/.openclaw/openclaw.json`:
```json
{
  "mcp": {
    "servers": {
      "heygen": { "url": "https://mcp.heygen.com/mcp/v1/" }
    }
  }
}
```

The first call triggers an OAuth consent flow in your browser.

> **Priority:** If `HEYGEN_API_KEY` is set, the skills use the CLI. Otherwise they look for MCP tools. Set the key only if you want direct API access; otherwise use MCP.

### Step 4 — Create your avatar

Ask the user for a photo (URL or file), then use the **heygen-avatar** skill:

> Create my HeyGen avatar from this photo: [user's photo]

The skill uploads the photo, creates a persistent digital twin with a voice, and saves an `AVATAR-<NAME>.md` file for future use.

### Step 5 — Make your first video

Use the **heygen-video** skill to generate an intro video with the avatar you just created:

> Make a 30-60 second video of me introducing myself, casual tone.

The skill picks up the avatar automatically, writes a script, generates the video, and returns a share link.

**That's it. You're set up.** The avatar persists — every future video reuses it automatically.

---

## What's Included

Two skills that work standalone or chain together:

| Skill | What it does | Invoke |
|-------|-------------|--------|
| **heygen-avatar** | Photo → persistent digital twin (face + voice). Reusable across every video. | `/heygen-avatar` |
| **heygen-video** | Idea → script → prompt-engineered video with your avatar delivering the message. | `/heygen-video` |

**heygen-avatar** creates the identity. **heygen-video** uses it.

## How It Works

```
Photo / Description          Avatar File              Finished Video
       ↓                        ↓                        ↓
  heygen-avatar    →    AVATAR-NAME.md       →    heygen-video
  (identity + voice)    (reusable state)          (script + video)
```

Skills communicate through `AVATAR-<NAME>.md` files. heygen-avatar writes them, heygen-video reads them. Human-readable and machine-readable.

## Authentication

The skills support two auth modes with explicit priority:

| Priority | Mode | Trigger | Billing | Best for |
|----------|------|---------|---------|----------|
| 1 | **CLI (API key)** | `HEYGEN_API_KEY` is set | Direct API usage ($, separately billed) | Agents, CI, scripts |
| 2 | **MCP (OAuth)** | MCP tools visible AND no API key | HeyGen plan credits (no extra billing) | Users on a HeyGen plan |
| 3 | **CLI (fallback)** | `heygen auth login` session | Direct API usage ($) | Interactive CLI users |

**Billing tradeoff:** CLI mode bills against your HeyGen API usage (separately metered). MCP mode consumes your existing HeyGen plan credits — no extra API billing. Pick the mode that matches how you want to be charged.

### CLI with API key (recommended for agents)

Get a key at **[app.heygen.com/api](https://app.heygen.com/api)**, then:

```bash
export HEYGEN_API_KEY=your-key-here
```

If `HEYGEN_API_KEY` is set, the skills use the CLI directly. No MCP probing. This is the most predictable setup for agent workflows.

The [HeyGen CLI](https://github.com/heygen-com/heygen-cli) pattern is `heygen <noun> <verb>`. Output is JSON on stdout with stable exit codes.

- **Verify**: `heygen auth status`
- **Alternative login**: `heygen auth login` — interactive browser flow, persists to `~/.heygen/credentials`

### MCP (OAuth, no API key)

If you don't set an API key and HeyGen's remote MCP server is connected to your agent, the skills use MCP via OAuth. Calls run against your existing HeyGen plan credits.

- Endpoint: `https://mcp.heygen.com/mcp/v1/`
- Tool namespace: `mcp__heygen__*`
- [MCP docs](https://developers.heygen.com/docs/mcp-remote)

You can have both configured — if `HEYGEN_API_KEY` is set, CLI wins.

## Things to Try

After setup, try these prompts with your agent:

| Prompt | What happens |
|--------|-------------|
| "Use heygen-avatar and heygen-video to make a 30-second cinematic intro of me as a founder. Ask me what you need." | Full pipeline: avatar → style recommendation → video. The wow moment. |
| "I want to make a product launch video. Use heygen-video and suggest the best style for it." | Skill recommends from 20 curated styles (A24, editorial, clean tech, etc.) |
| "Use heygen-avatar — I have a headshot. What kind of look would work best for a founder intro?" | Skill asks questions, recommends setting and tone before creating |
| "Use heygen-video to summarize this article as a 60-second explainer from my avatar: [URL]" | Fetches content, extracts key points, scripts and generates the video |
| "Use heygen-video to turn the key points from this PDF into a video update for my team: [file]" | PDF → script → avatar video. Any content becomes a video message. |
| "Use heygen-video for my team's weekly update. Ask me what shipped before writing the script." | Skill interviews you first, then writes and generates |
| "Use heygen-video to make a 20-second outreach video to a potential investor. What should I include?" | Skill guides the message, you approve the script, avatar delivers it |
| "Use heygen-avatar to give me a new look — ask me what vibe I'm going for." | Discovery flow: skill suggests options (outdoor, studio, casual, cinematic) before committing |

## Requirements

- A HeyGen account — sign in via MCP (OAuth) or with an [API key](https://app.heygen.com/api) if you use the CLI fallback
- An AI agent that supports skills (Claude Code, OpenClaw, Codex, Cursor, or similar)
- No runtime dependencies. No packages. No build step.

## Security

One optional shell script:

- **`scripts/update-check.sh`** — compares your local `VERSION` against the latest on GitHub. Read-only, opt-in, no data transmitted.

Data only leaves your machine through MCP / the `heygen` CLI (video generation) and optionally `raw.githubusercontent.com` (version check).

## Looking for the v1 skills?

The previous version of this repo had individual skills for TTS, video translation, faceswap, video editing, and more. Those skills are preserved at [heygen-com/skills-legacy](https://github.com/heygen-com/skills-legacy).

## Links

- [HeyGen API Docs](https://developers.heygen.com/docs/quick-start)
- [Repository](https://github.com/heygen-com/skills)
- [Contributing](CONTRIBUTING.md)
- [Changelog](CHANGELOG.md)

## License

MIT


path: assets/PRISM_ORB.svg
content: <svg width="286" height="286" viewBox="0 0 286 286" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_38479_43706)">
<path d="M126.577 246.167C126.577 246.167 56.9989 192.871 46.3968 184.839C40.4925 180.37 34.0742 169.896 35.4093 161.657C36.4036 155.535 39.9395 152.39 44.7322 150.72C59.6578 145.508 107.021 129.152 119.751 125.064C126.767 122.807 137.906 124.874 146.223 131.672C152.815 137.057 158.021 144.95 158.088 155.127C158.238 178.152 159.456 232.045 159.456 238.978C159.456 242.932 157.792 249.636 149.999 251.987C142.414 254.272 132.979 251.071 126.572 246.167H126.577Z" fill="url(#paint0_linear_38479_43706)"/>
<path d="M145.709 132.13C152.301 137.515 157.289 145.011 157.356 155.189C157.507 178.214 159.462 232.051 159.462 238.983C159.462 232.051 158.998 177.242 158.847 154.211C158.697 131.186 133.549 119.215 120.975 123.762C108.401 128.309 59.6634 145.514 44.7378 150.725C59.6634 145.514 107.261 129.761 119.992 125.672C127.007 123.416 137.397 125.332 145.715 132.13H145.709Z" fill="url(#paint1_linear_38479_43706)"/>
<path d="M145.709 132.13C152.301 137.515 157.289 145.011 157.356 155.189C157.507 178.214 159.462 232.051 159.462 238.983C159.462 232.051 158.998 177.242 158.847 154.211C158.697 131.186 133.549 119.215 120.975 123.762C108.401 128.309 59.6634 145.514 44.7378 150.725C59.6634 145.514 107.261 129.761 119.992 125.672C127.007 123.416 137.397 125.332 145.715 132.13H145.709Z" fill="#AB81E9"/>
<path d="M126.577 246.167C126.577 246.167 56.9989 192.871 46.3968 184.839C40.4925 180.37 34.0742 169.896 35.4093 161.657C36.4036 155.535 39.9395 152.39 44.7322 150.72C59.6578 145.508 107.021 129.152 119.751 125.064C126.767 122.807 137.906 124.874 146.223 131.672C152.815 137.057 158.691 145.028 158.803 155.205C158.914 165.226 158.948 181.035 159.071 196.279C159.233 216.12 159.389 235.012 159.378 238.978C159.367 242.932 157.797 249.636 149.999 251.987C142.414 254.272 132.979 251.071 126.572 246.167H126.577Z" fill="url(#paint2_linear_38479_43706)"/>
<path d="M146.178 131.633C152.77 137.012 157.993 144.899 158.065 155.077C158.239 178.102 159.512 231.995 159.518 238.927C159.512 231.995 158.993 177.186 158.819 154.161C158.646 131.136 133.487 119.193 120.913 123.745C108.345 128.304 59.6244 145.558 44.6987 150.781C59.6188 145.558 106.971 129.153 119.696 125.053C126.711 122.79 137.85 124.84 146.173 131.633H146.178Z" fill="url(#paint3_radial_38479_43706)"/>
<path d="M146.178 131.633C152.77 137.012 157.993 144.899 158.065 155.077C158.239 178.102 159.512 231.995 159.518 238.927C159.512 231.995 158.993 177.186 158.819 154.161C158.646 131.136 133.487 119.193 120.913 123.745C108.345 128.304 59.6244 145.558 44.6987 150.781C59.6188 145.558 106.971 129.153 119.696 125.053C126.711 122.79 137.85 124.84 146.173 131.633H146.178Z" fill="url(#paint4_radial_38479_43706)"/>
<path d="M126.929 123.36C130.175 123.36 133.75 124.08 137.269 125.449C140.928 126.868 144.447 128.968 147.43 131.51C150.714 134.308 153.317 137.571 155.166 141.207C157.211 145.229 158.261 149.603 158.289 154.211C158.35 163.78 158.468 178.979 158.585 193.676C158.747 214.891 158.903 234.928 158.903 238.978C158.903 240.38 158.68 243.139 157.166 245.809C155.619 248.558 153.15 250.457 149.837 251.451C148.234 251.937 146.48 252.183 144.631 252.183C141.693 252.183 138.459 251.552 135.286 250.356C132.292 249.228 129.393 247.63 126.907 245.725C126.209 245.189 57.2057 192.335 46.7208 184.397C43.7547 182.152 40.7439 178.415 38.6715 174.41C37.5487 172.242 36.7388 170.086 36.264 168.008C35.7501 165.752 35.6439 163.646 35.9512 161.752C36.4092 158.92 37.4258 156.68 39.0514 154.898C40.4981 153.312 42.4141 152.116 44.911 151.245C60.2667 145.888 108.591 128.823 121.153 124.282C122.84 123.673 124.784 123.36 126.924 123.36M126.929 122.807C124.762 122.807 122.74 123.12 120.969 123.762C108.395 128.309 59.6579 145.514 44.7323 150.725C39.9395 152.396 36.4036 155.54 35.4093 161.663C34.0687 169.902 40.4925 180.37 46.3969 184.844C56.999 192.877 126.577 246.172 126.577 246.172C131.538 249.971 138.313 252.747 144.642 252.747C146.486 252.747 148.296 252.512 150.005 251.993C157.797 249.641 159.462 242.938 159.462 238.983C159.462 232.051 158.998 177.242 158.847 154.211C158.719 134.426 140.14 122.807 126.935 122.807H126.929Z" fill="url(#paint5_linear_38479_43706)"/>
<path d="M171.198 152.558C171.198 146.251 173.605 135.9 179.253 127.879C182.431 123.366 186.442 119.243 190.592 117.355C193.821 115.886 195.368 115.646 199.194 116.433C199.194 116.433 245.597 126.382 248.429 126.957C251.261 127.533 254.344 129.454 254.758 135.353C255.171 141.252 253.618 150.575 247.01 160.194C240.408 169.807 200.194 227.89 195.15 235.174C190.101 242.458 182.515 247.105 178.214 245.971C172.751 244.53 171.583 239.497 171.622 236.023C171.7 229.61 171.198 152.563 171.198 152.563V152.558Z" fill="url(#paint6_linear_38479_43706)"/>
<path d="M178.208 244.893C173.147 243.519 173.421 239.642 173.376 236.017C173.287 229.314 172.957 152.558 172.957 152.558C172.957 146.251 175.136 137.124 180.783 129.102C183.962 124.589 186.816 121.176 190.721 118.925C193.798 117.16 196.781 116.741 200.608 117.534C200.608 117.534 245.597 126.382 248.429 126.957C245.597 126.382 199.194 116.433 199.194 116.433C195.363 115.64 193.821 115.886 190.592 117.355C186.442 119.243 182.431 123.366 179.253 127.879C173.6 135.906 171.198 146.251 171.198 152.558C171.198 152.558 171.7 229.605 171.622 236.017C171.578 239.492 172.745 244.525 178.214 245.966C182.52 247.1 190.101 242.452 195.15 235.168C190.101 242.452 182.509 246.066 178.214 244.899L178.208 244.893Z" fill="url(#paint7_linear_38479_43706)"/>
<path d="M178.208 244.893C173.147 243.519 173.421 239.642 173.376 236.017C173.287 229.314 172.957 152.558 172.957 152.558C172.957 146.251 175.136 137.124 180.783 129.102C183.962 124.589 186.816 121.176 190.721 118.925C193.798 117.16 196.781 116.741 200.608 117.534C200.608 117.534 245.597 126.382 248.429 126.957C245.597 126.382 199.194 116.433 199.194 116.433C195.363 115.64 193.821 115.886 190.592 117.355C186.442 119.243 182.431 123.366 179.253 127.879C173.6 135.906 171.198 146.251 171.198 152.558C171.198 152.558 171.7 229.605 171.622 236.017C171.578 239.492 172.745 244.525 178.214 245.966C182.52 247.1 190.101 242.452 195.15 235.168C190.101 242.452 182.509 246.066 178.214 244.899L178.208 244.893Z" fill="#00BA97"/>
<path d="M172.957 152.558C172.957 146.251 175.13 137.124 180.783 129.102C183.962 124.589 186.816 121.176 190.726 118.925C193.804 117.16 196.787 116.741 200.613 117.534C200.613 117.534 245.602 126.382 248.434 126.957C251.267 127.533 254.35 129.454 254.763 135.353C255.177 141.252 253.618 150.575 247.016 160.194C240.413 169.807 200.205 227.89 195.156 235.174C190.106 242.458 182.515 247.139 178.219 245.971C173.158 244.597 173.432 239.648 173.387 236.023C173.298 229.32 172.968 152.563 172.968 152.563L172.957 152.558Z" fill="url(#paint8_linear_38479_43706)"/>
<path d="M178.208 244.893C173.147 243.519 173.421 239.642 173.376 236.017C173.287 229.314 172.957 152.558 172.957 152.558C172.957 146.251 175.136 137.124 180.783 129.102C183.962 124.589 186.816 121.176 190.721 118.925C193.798 117.16 196.781 116.741 200.608 117.534C200.608 117.534 245.597 126.382 248.429 126.957C245.597 126.382 199.194 116.433 199.194 116.433C195.363 115.64 193.821 115.886 190.592 117.355C186.442 119.243 182.431 123.366 179.253 127.879C173.6 135.906 171.198 146.251 171.198 152.558C171.198 152.558 171.7 229.605 171.622 236.017C171.578 239.492 172.745 244.525 178.214 245.966C182.52 247.1 190.101 242.452 195.15 235.168C190.101 242.452 182.509 246.066 178.214 244.899L178.208 244.893Z" fill="url(#paint9_radial_38479_43706)"/>
<path d="M178.208 244.893C173.147 243.519 173.421 239.642 173.376 236.017C173.287 229.314 172.957 152.558 172.957 152.558C172.957 146.251 175.136 137.124 180.783 129.102C183.962 124.589 186.816 121.176 190.721 118.925C193.798 117.16 196.781 116.741 200.608 117.534C200.608 117.534 245.597 126.382 248.429 126.957C245.597 126.382 199.194 116.433 199.194 116.433C195.363 115.64 193.821 115.886 190.592 117.355C186.442 119.243 182.431 123.366 179.253 127.879C173.6 135.906 171.198 146.251 171.198 152.558C171.198 152.558 171.7 229.605 171.622 236.017C171.578 239.492 172.745 244.525 178.214 245.966C182.52 247.1 190.101 242.452 195.15 235.168C190.101 242.452 182.509 246.066 178.214 244.899L178.208 244.893Z" fill="url(#paint10_radial_38479_43706)"/>
<path d="M195.687 115.987V116.607C196.586 116.607 197.63 116.741 199.072 117.037C199.552 117.137 245.507 126.996 248.312 127.561C249.859 127.873 251.116 128.549 252.049 129.572C253.261 130.901 253.97 132.862 254.143 135.392C254.305 137.705 254.222 141.481 252.92 146.329C251.635 151.122 249.473 155.742 246.502 160.065C239.938 169.623 200.004 227.309 194.642 235.04C192.519 238.095 189.799 240.86 186.978 242.826C184.274 244.709 181.655 245.742 179.61 245.742C179.163 245.742 178.75 245.692 178.37 245.591C176.102 244.994 174.432 243.687 173.404 241.692C172.415 239.776 172.226 237.676 172.242 236.246C172.321 229.912 171.823 153.714 171.818 152.776C171.818 149.396 172.471 145.179 173.605 141.207C174.985 136.381 177.046 131.94 179.565 128.365C183.073 123.382 187.185 119.573 190.849 117.902C192.715 117.053 194.039 116.595 195.687 116.595V115.975M195.687 115.987C193.994 115.987 192.631 116.428 190.592 117.349C186.442 119.238 182.236 123.5 179.057 128.013C173.404 136.04 171.198 146.48 171.198 152.787C171.198 152.787 171.7 229.839 171.622 236.246C171.578 239.721 172.745 244.754 178.214 246.195C178.649 246.306 179.113 246.362 179.61 246.362C184.023 246.362 190.609 241.944 195.15 235.392C200.2 228.107 240.408 170.03 247.016 160.411C253.618 150.798 255.171 141.241 254.763 135.342C254.35 129.443 251.267 127.521 248.435 126.946C245.602 126.371 199.2 116.422 199.2 116.422C197.787 116.132 196.681 115.981 195.687 115.981V115.987Z" fill="url(#paint11_linear_38479_43706)"/>
<path d="M31.1807 135.23C31.1807 131.002 33.9904 124.656 37.6883 120.238C37.6883 120.238 93.2795 53.4911 97.0333 48.9721C100.793 44.4531 108.317 38.6326 114.065 36.2083C119.813 33.7895 123.589 34.3593 125.309 38.0963C127.035 41.8333 141.57 73.7346 143.307 77.533C144.949 81.1248 144.653 84.2808 141.263 91.0286C136.962 99.5863 125.533 109.613 117.807 112.428C109.322 115.523 47.7374 137.917 41.2968 140.246C34.8562 142.581 31.1863 138.867 31.1863 135.225L31.1807 135.23Z" fill="url(#paint12_linear_38479_43706)"/>
<path d="M143.302 77.5274C141.57 73.729 127.03 41.8277 125.304 38.0907C124.108 35.4932 121.919 34.4263 118.768 34.8285C121.556 34.5269 123.282 35.6552 124.455 38.1913C126.181 41.9282 140.201 72.2934 141.877 76.1142C143.235 79.1976 143.251 82.4151 140.118 88.5876C135.984 96.7207 124.287 107.714 116.567 110.529C108.082 113.624 46.1007 136.403 39.6657 138.738C33.2251 141.073 31.5996 138.051 31.5996 134.409C31.5996 131.912 32.4375 128.957 33.8843 126.047C32.2308 129.281 31.1863 132.644 31.1863 135.219C31.1863 138.861 34.8618 142.57 41.2968 140.241C47.7374 137.906 109.317 115.517 117.807 112.423C125.533 109.602 136.962 99.5751 141.263 91.023C144.653 84.2752 144.949 81.1192 143.307 77.5274H143.302Z" fill="url(#paint13_linear_38479_43706)"/>
<path d="M143.302 77.5274C141.57 73.729 127.03 41.8277 125.304 38.0907C124.108 35.4932 121.919 34.4263 118.768 34.8285C121.556 34.5269 123.282 35.6552 124.455 38.1913C126.181 41.9282 140.201 72.2934 141.877 76.1142C143.235 79.1976 143.251 82.4151 140.118 88.5876C135.984 96.7207 124.287 107.714 116.567 110.529C108.082 113.624 46.1007 136.403 39.6657 138.738C33.2251 141.073 31.5996 138.051 31.5996 134.409C31.5996 131.912 32.4375 128.957 33.8843 126.047C32.2308 129.281 31.1863 132.644 31.1863 135.219C31.1863 138.861 34.8618 142.57 41.2968 140.241C47.7374 137.906 109.317 115.517 117.807 112.423C125.533 109.602 136.962 99.5751 141.263 91.023C144.653 84.2752 144.949 81.1192 143.307 77.5274H143.302Z" fill="#128414"/>
<path d="M31.594 134.414C31.594 130.186 33.9904 124.656 37.6883 120.237C37.6883 120.237 93.2795 53.491 97.0333 48.972C100.793 44.453 108.317 38.6324 114.065 36.2081C119.813 33.7894 122.734 34.4597 124.46 38.1967C126.186 41.9337 140.201 72.2989 141.883 76.1196C143.24 79.2031 143.257 82.4206 140.123 88.593C135.99 96.7262 124.293 107.719 116.573 110.535C108.088 113.629 46.1063 136.409 39.6713 138.744C33.2307 141.079 31.6052 138.057 31.6052 134.414H31.594Z" fill="url(#paint14_linear_38479_43706)"/>
<path d="M143.302 77.5274C141.57 73.729 127.03 41.8277 125.304 38.0907C124.108 35.4932 121.919 34.4263 118.768 34.8285C121.556 34.5269 123.282 35.6552 124.455 38.1913C126.181 41.9282 140.201 72.2934 141.877 76.1142C143.235 79.1976 143.251 82.4151 140.118 88.5876C135.984 96.7207 124.287 107.714 116.567 110.529C108.082 113.624 46.1007 136.403 39.6657 138.738C33.2251 141.073 31.5996 138.051 31.5996 134.409C31.5996 131.912 32.4375 128.957 33.8843 126.047C32.2308 129.281 31.1863 132.644 31.1863 135.219C31.1863 138.861 34.8618 142.57 41.2968 140.241C47.7374 137.906 109.317 115.517 117.807 112.423C125.533 109.602 136.962 99.5751 141.263 91.023C144.653 84.2752 144.949 81.1192 143.307 77.5274H143.302Z" fill="url(#paint15_radial_38479_43706)"/>
<path d="M143.302 77.5274C141.57 73.729 127.03 41.8277 125.304 38.0907C124.108 35.4932 121.919 34.4263 118.768 34.8285C121.556 34.5269 123.282 35.6552 124.455 38.1913C126.181 41.9282 140.201 72.2934 141.877 76.1142C143.235 79.1976 143.251 82.4151 140.118 88.5876C135.984 96.7207 124.287 107.714 116.567 110.529C108.082 113.624 46.1007 136.403 39.6657 138.738C33.2251 141.073 31.5996 138.051 31.5996 134.409C31.5996 131.912 32.4375 128.957 33.8843 126.047C32.2308 129.281 31.1863 132.644 31.1863 135.219C31.1863 138.861 34.8618 142.57 41.2968 140.241C47.7374 137.906 109.317 115.517 117.807 112.423C125.533 109.602 136.962 99.5751 141.263 91.023C144.653 84.2752 144.949 81.1192 143.307 77.5274H143.302Z" fill="#128414"/>
<path d="M143.302 77.5274C141.57 73.729 127.03 41.8277 125.304 38.0907C124.108 35.4932 121.919 34.4263 118.768 34.8285C121.556 34.5269 123.282 35.6552 124.455 38.1913C126.181 41.9282 140.201 72.2934 141.877 76.1142C143.235 79.1976 143.251 82.4151 140.118 88.5876C135.984 96.7207 124.287 107.714 116.567 110.529C108.082 113.624 46.1007 136.403 39.6657 138.738C33.2251 141.073 31.5996 138.051 31.5996 134.409C31.5996 131.912 32.4375 128.957 33.8843 126.047C32.2308 129.281 31.1863 132.644 31.1863 135.219C31.1863 138.861 34.8618 142.57 41.2968 140.241C47.7374 137.906 109.317 115.517 117.807 112.423C125.533 109.602 136.962 99.5751 141.263 91.023C144.653 84.2752 144.949 81.1192 143.307 77.5274H143.302Z" fill="url(#paint16_radial_38479_43706)"/>
<path d="M120.003 35.5267C122.198 35.5267 123.516 36.6159 124.416 38.5654C125.806 41.5818 135.71 62.7414 140.375 72.9804C141.464 75.3712 142.268 77.1308 142.598 77.8569C143.413 79.6444 143.654 81.1806 143.397 82.9904C143.117 84.9622 142.246 87.3307 140.564 90.6822C139.548 92.6988 138.107 94.8549 136.263 97.0949C134.515 99.2231 132.51 101.312 130.292 103.306C125.857 107.3 121.204 110.361 117.534 111.702C109.378 114.679 47.7374 137.09 41.0287 139.52C39.783 139.973 38.5932 140.202 37.5039 140.202C35.817 140.202 34.387 139.654 33.3648 138.626C32.471 137.721 31.9515 136.487 31.9515 135.23C31.9515 133.303 32.5939 130.778 33.7558 128.114C34.9177 125.455 36.5208 122.829 38.2804 120.729C38.8334 120.064 93.9107 53.9324 97.6254 49.4636C99.4241 47.3018 102.211 44.7323 105.267 42.4197C108.468 39.9954 111.702 38.0404 114.361 36.9232C116.562 35.9959 118.455 35.5267 120.003 35.5267ZM120.003 34.7502C118.344 34.7502 116.361 35.2418 114.059 36.2082C108.311 38.6269 100.787 44.453 97.0277 48.972C93.2684 53.4911 37.6827 120.237 37.6827 120.237C33.9904 124.656 31.1807 131.002 31.1807 135.23C31.1807 138.085 33.4318 140.978 37.5039 140.978C38.6323 140.978 39.8947 140.755 41.2912 140.252C47.7318 137.917 109.311 115.528 117.802 112.434C125.527 109.613 136.956 99.5862 141.257 91.0342C144.648 84.2863 144.944 81.1303 143.302 77.5385C141.57 73.7401 127.03 41.8388 125.304 38.1018C124.27 35.8618 122.494 34.7558 119.997 34.7558L120.003 34.7502Z" fill="url(#paint17_linear_38479_43706)"/>
<path d="M140.028 38.6157C138.933 36.264 138.772 35.644 139.392 34.767C140.012 33.89 140.252 32.851 143.302 33.4487C146.352 34.0464 152.926 36.6439 164.176 44.9948C175.426 53.3458 224.996 90.2018 232.816 96.0056C240.637 101.804 246.323 108.077 247.435 110.758C248.334 112.858 247.921 113.305 247.295 114.048C246.776 114.668 246.435 115.316 244.631 115.132C244.631 115.132 238.19 113.73 230.571 111.959C222.952 110.188 203.68 105.764 194.357 103.597C185.034 101.424 174.566 93.6093 170.874 90.6711C168.422 88.716 164.646 85.6661 160.763 81.0074C159.199 79.1305 158.138 77.2648 156.747 74.2316C152.524 65.0037 140.017 38.6213 140.017 38.6213L140.028 38.6157Z" fill="url(#paint18_radial_38479_43706)"/>
<path d="M246.787 109.786C247.105 110.697 247.29 112.356 246.826 112.803C246.401 113.21 245.619 113.054 244.201 112.724C244.201 112.724 238.777 111.205 231.157 109.434C223.538 107.664 204.255 102.988 194.933 100.821C185.61 98.6478 176.382 91.2297 172.689 88.2859C170.237 86.3308 167.288 83.9791 163.405 79.3149C161.841 77.438 159.495 73.0475 158.049 70.0366C153.63 60.8366 141.793 37.3477 141.793 37.3477C140.699 34.996 140.889 34.3146 141.419 33.8621C141.682 33.6387 142.268 33.5828 143.698 33.8286C146.67 34.3369 152.541 36.5042 163.137 44.2352C152.518 36.4875 146.257 34.0297 143.302 33.4543C140.252 32.8566 140.012 33.8956 139.392 34.7726C138.772 35.6496 138.933 36.2696 140.028 38.6213C140.028 38.6213 152.535 65.0093 156.758 74.2317C158.149 77.2648 159.21 79.1305 160.775 81.0074C164.657 85.6661 168.433 88.716 170.885 90.6711C174.577 93.6149 185.045 101.43 194.368 103.597C203.691 105.77 222.963 110.188 230.582 111.959C238.201 113.73 244.642 115.132 244.642 115.132C246.446 115.316 246.787 114.668 247.306 114.048C247.926 113.305 247.692 111.881 246.792 109.781L246.787 109.786Z" fill="url(#paint19_radial_38479_43706)"/>
<path d="M246.787 109.786C247.105 110.697 247.29 112.356 246.826 112.803C246.401 113.21 245.619 113.054 244.201 112.724C244.201 112.724 238.777 111.205 231.157 109.434C223.538 107.664 204.255 102.988 194.933 100.821C185.61 98.6478 176.382 91.2297 172.689 88.2859C170.237 86.3308 167.288 83.9791 163.405 79.3149C161.841 77.438 159.495 73.0475 158.049 70.0366C153.63 60.8366 141.793 37.3477 141.793 37.3477C140.699 34.996 140.889 34.3146 141.419 33.8621C141.682 33.6387 142.268 33.5828 143.698 33.8286C146.67 34.3369 152.541 36.5042 163.137 44.2352C152.518 36.4875 146.257 34.0297 143.302 33.4543C140.252 32.8566 140.012 33.8956 139.392 34.7726C138.772 35.6496 138.933 36.2696 140.028 38.6213C140.028 38.6213 152.535 65.0093 156.758 74.2317C158.149 77.2648 159.21 79.1305 160.775 81.0074C164.657 85.6661 168.433 88.716 170.885 90.6711C174.577 93.6149 185.045 101.43 194.368 103.597C203.691 105.77 222.963 110.188 230.582 111.959C238.201 113.73 244.642 115.132 244.642 115.132C246.446 115.316 246.787 114.668 247.306 114.048C247.926 113.305 247.692 111.881 246.792 109.781L246.787 109.786Z" fill="#0079FF"/>
<path d="M140.922 37.5823C139.827 35.2306 139.877 34.1861 140.408 33.7336C140.671 33.5102 142.307 33.3314 143.726 33.6498C146.809 34.3425 152.926 36.6383 164.182 44.9949C175.432 53.3458 224.677 90.3527 232.503 96.1565C240.324 101.955 245.803 107.915 246.915 110.596C247.233 111.507 247.792 112.937 247.323 113.383C246.898 113.791 246.373 113.853 244.954 113.523C244.954 113.523 238.464 111.825 230.844 110.054C223.225 108.284 204.233 103.731 194.91 101.564C185.587 99.3907 176.208 91.9 172.516 88.9618C170.064 87.0067 166.729 84.4763 162.847 79.812C161.283 77.9351 159.411 76.0862 158.02 73.0474C153.797 63.8195 140.927 37.5879 140.927 37.5879L140.922 37.5823Z" fill="url(#paint20_linear_38479_43706)"/>
<path d="M140.922 37.5823C139.827 35.2306 139.877 34.1861 140.408 33.7336C140.671 33.5102 142.307 33.3314 143.726 33.6498C146.809 34.3425 152.926 36.6383 164.182 44.9949C175.432 53.3458 224.677 90.3527 232.503 96.1565C240.324 101.955 245.803 107.915 246.915 110.596C247.233 111.507 247.792 112.937 247.323 113.383C246.898 113.791 246.373 113.853 244.954 113.523C244.954 113.523 238.464 111.825 230.844 110.054C223.225 108.284 204.233 103.731 194.91 101.564C185.587 99.3907 176.208 91.9 172.516 88.9618C170.064 87.0067 166.729 84.4763 162.847 79.812C161.283 77.9351 159.411 76.0862 158.02 73.0474C153.797 63.8195 140.927 37.5879 140.927 37.5879L140.922 37.5823Z" fill="url(#paint21_linear_38479_43706)" fill-opacity="0.2"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C247.479 113.316 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="url(#paint22_radial_38479_43706)"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.664 114.434 247.189 113.808C247.809 113.065 247.474 111.83 246.345 109.792L246.329 109.786Z" fill="#00E1FF"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C247.479 113.316 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="#00E1FF"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C247.479 113.316 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="url(#paint23_radial_38479_43706)"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C248.083 112.786 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="url(#paint24_linear_38479_43706)" fill-opacity="0.7"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C247.479 113.316 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="url(#paint25_radial_38479_43706)"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C247.479 113.316 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="url(#paint26_radial_38479_43706)"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C247.479 113.316 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="url(#paint27_radial_38479_43706)"/>
<path d="M246.329 109.786C246.647 110.697 246.831 112.356 246.368 112.802C245.943 113.21 245.161 113.054 243.742 112.724C243.742 112.724 238.318 111.205 230.699 109.434C223.08 107.663 203.797 102.988 194.474 100.821C185.151 98.6477 175.923 91.2296 172.231 88.2858C169.779 86.3307 166.98 83.521 163.104 78.8623C161.54 76.9854 159.266 73.0529 157.819 70.0421C153.401 60.8421 141.643 37.3532 141.643 37.3532C140.548 35.0015 140.436 34.32 140.967 33.8676C141.229 33.6441 141.81 33.5883 143.246 33.834C146.217 34.3424 152.088 36.5097 162.685 44.2406C152.066 36.493 145.815 33.9905 142.849 33.4598C140.173 32.9794 139.984 34.0687 139.336 34.9792C138.838 35.6774 138.939 36.2751 140.039 38.6268C140.039 38.6268 152.261 64.3891 156.484 73.6171C157.875 76.6503 159.221 79.136 160.786 81.0129C164.668 85.6715 168.114 88.4142 170.572 90.3693C174.264 93.3131 184.598 101.284 193.921 103.457C203.244 105.63 222.516 110.049 230.135 111.819C237.754 113.59 244.195 115.07 244.195 115.07C245.999 115.255 246.34 114.685 246.859 114.059C247.479 113.316 247.245 111.892 246.345 109.792L246.329 109.786Z" fill="url(#paint28_radial_38479_43706)"/>
<path d="M246.58 109.909C246.898 110.82 247.083 112.479 246.619 112.925C246.189 113.333 245.413 113.177 243.994 112.847C243.994 112.847 238.57 111.328 230.951 109.557C223.331 107.786 204.049 103.111 194.726 100.944C185.403 98.7707 176.175 91.3526 172.483 88.4088C170.03 86.4537 167.232 83.644 163.355 78.9853C161.791 77.1085 159.518 73.176 158.071 70.1651C153.652 60.9651 141.894 37.4762 141.894 37.4762C140.799 35.1246 140.687 34.4431 141.218 33.9906C141.481 33.7672 142.062 33.7113 143.497 33.9571C146.469 34.4654 152.34 36.6328 162.936 44.3637C152.317 36.616 146.067 34.1135 143.101 33.5828C140.425 33.1024 140.235 34.1917 139.587 35.1022C139.084 35.8005 139.19 36.3982 140.291 38.7498C140.291 38.7498 152.513 64.5122 156.736 73.7401C158.127 76.7733 159.473 79.259 161.037 81.1359C164.919 85.7946 168.366 88.5373 170.824 90.4924C174.516 93.4362 184.85 101.407 194.173 103.58C203.496 105.753 222.773 110.172 230.386 111.942C238.006 113.713 244.446 115.193 244.446 115.193C246.251 115.378 246.591 114.808 247.111 114.182C247.731 113.439 247.496 112.015 246.597 109.915L246.58 109.909Z" fill="url(#paint29_radial_38479_43706)"/>
<path d="M141.743 33.8845C142.14 33.8845 142.62 33.9403 143.184 34.052C144.475 34.3034 146.765 34.9961 150.385 36.8618C154.3 38.8783 158.819 41.783 163.813 45.4921C169.232 49.5139 183.755 60.306 197.793 70.7461C212.841 81.9291 228.398 93.4976 232.453 96.5028C237 99.8767 240.262 102.977 242.206 104.982C244.592 107.451 246.34 109.702 246.876 110.998V111.004C247.239 111.847 247.39 112.44 247.334 112.814C247.295 113.093 247.195 113.3 246.899 113.652L246.871 113.685C246.82 113.741 246.776 113.797 246.731 113.858C246.362 114.311 245.971 114.277 245.083 114.277C244.938 114.277 244.776 114.272 244.597 114.249C243.385 114.015 237.95 113.048 230.71 111.367C227.286 110.568 222.08 109.004 215.93 107.585C208.21 105.809 199.625 104.195 194.497 102.999C190.542 102.078 185.945 100.028 180.822 96.8994C176.549 94.2852 172.991 91.576 171.254 90.1907C168.316 87.8502 165.132 84.9902 161.49 80.6164C160.009 78.8178 158.898 77.0023 157.456 73.8519C153.289 64.7412 140.743 38.7107 140.576 38.3532C139.442 35.9233 139.503 35.6552 139.883 35.1134C139.961 35.0072 140.028 34.9011 140.095 34.795C140.464 34.2196 140.687 33.8733 141.738 33.8733L141.743 33.8845ZM141.743 33.2756C140.134 33.2756 139.883 34.0744 139.392 34.7671C138.772 35.644 138.933 36.2641 140.028 38.6158C140.028 38.6158 152.535 65.0037 156.758 74.2261C158.149 77.2593 159.032 79.3428 160.596 81.2197C164.478 85.8784 168.288 88.9506 170.745 90.9057C174.438 93.8495 184.984 101.821 194.307 103.988C203.63 106.161 222.963 110.188 230.582 111.959C238.201 113.73 244.642 115.132 244.642 115.132C244.854 115.154 245.044 115.165 245.217 115.165C246.524 115.165 246.843 114.596 247.306 114.048C247.926 113.305 248.345 112.864 247.446 110.758C246.334 108.071 240.648 101.804 232.828 96.0057C225.007 90.2075 175.438 53.3459 164.188 44.9949C152.937 36.6439 146.363 34.0465 143.313 33.4488C142.682 33.3259 142.173 33.27 141.754 33.27L141.743 33.2756Z" fill="url(#paint30_linear_38479_43706)"/>
<path d="M141.743 33.8845C142.14 33.8845 142.62 33.9403 143.184 34.052C144.475 34.3034 146.765 34.9961 150.385 36.8618C154.3 38.8783 158.819 41.783 163.813 45.4921C169.232 49.5139 183.755 60.306 197.793 70.7461C212.841 81.9291 228.398 93.4976 232.453 96.5028C237 99.8767 240.262 102.977 242.206 104.982C244.592 107.451 246.34 109.702 246.876 110.998V111.004C247.239 111.847 247.39 112.44 247.334 112.814C247.295 113.093 247.195 113.3 246.899 113.652L246.871 113.685C246.82 113.741 246.776 113.797 246.731 113.858C246.362 114.311 245.971 114.277 245.083 114.277C244.938 114.277 244.776 114.272 244.597 114.249C243.385 114.015 237.95 113.048 230.71 111.367C227.286 110.568 222.08 109.004 215.93 107.585C208.21 105.809 199.625 104.195 194.497 102.999C190.542 102.078 185.945 100.028 180.822 96.8994C176.549 94.2852 172.991 91.576 171.254 90.1907C168.316 87.8502 165.132 84.9902 161.49 80.6164C160.009 78.8178 158.898 77.0023 157.456 73.8519C153.289 64.7412 140.743 38.7107 140.576 38.3532C139.442 35.9233 139.503 35.6552 139.883 35.1134C139.961 35.0072 140.028 34.9011 140.095 34.795C140.464 34.2196 140.687 33.8733 141.738 33.8733L141.743 33.8845ZM141.743 33.2756C140.134 33.2756 139.883 34.0744 139.392 34.7671C138.772 35.644 138.933 36.2641 140.028 38.6158C140.028 38.6158 152.535 65.0037 156.758 74.2261C158.149 77.2593 159.032 79.3428 160.596 81.2197C164.478 85.8784 168.288 88.9506 170.745 90.9057C174.438 93.8495 184.984 101.821 194.307 103.988C203.63 106.161 222.963 110.188 230.582 111.959C238.201 113.73 244.642 115.132 244.642 115.132C244.854 115.154 245.044 115.165 245.217 115.165C246.524 115.165 246.843 114.596 247.306 114.048C247.926 113.305 248.345 112.864 247.446 110.758C246.334 108.071 240.648 101.804 232.828 96.0057C225.007 90.2075 175.438 53.3459 164.188 44.9949C152.937 36.6439 146.363 34.0465 143.313 33.4488C142.682 33.3259 142.173 33.27 141.754 33.27L141.743 33.2756Z" fill="url(#paint31_linear_38479_43706)"/>
<path d="M141.732 33.8732C142.128 33.8732 142.62 33.9291 143.184 34.0408C144.48 34.2922 146.793 34.9904 150.435 36.8729C154.378 38.9061 158.925 41.8276 163.958 45.5646C169.416 49.6144 184.04 60.4846 198.178 70.9974C213.332 82.2586 229.001 93.9053 233.079 96.9329C237.659 100.329 240.944 103.452 242.899 105.474C245.301 107.96 247.06 110.227 247.602 111.535V111.54C247.965 112.389 247.786 112.752 247.736 113.126C247.602 113.4 247.552 113.59 247.256 113.942L247.228 113.976C247.178 114.031 247.133 114.087 247.088 114.149C246.72 114.607 246.491 114.886 245.597 114.886C245.452 114.886 245.284 114.875 245.111 114.858C244.586 114.746 238.62 113.601 231.33 111.909C227.884 111.104 222.035 109.758 215.841 108.334C208.065 106.541 199.535 105.027 194.368 103.826C190.385 102.899 185.755 100.832 180.599 97.6814C176.292 95.0504 172.711 92.3189 170.963 90.9224C168.003 88.5651 164.539 85.6772 160.875 81.2755C159.406 79.5103 158.367 77.7619 156.92 74.5891C152.725 65.417 140.738 38.7442 140.564 38.3811C139.425 35.9288 139.481 35.6663 139.866 35.1189C139.944 35.0127 140.011 34.901 140.078 34.8005C140.447 34.2251 140.676 33.8732 141.732 33.8732ZM141.732 33.2588C140.112 33.2588 139.855 34.0631 139.363 34.7614C138.743 35.644 138.9 36.2696 140.006 38.638C140.006 38.638 152.15 65.7131 156.401 75.0025C157.797 78.058 158.87 79.9349 160.445 81.8285C164.355 86.5207 168.153 89.5929 170.628 91.5592C174.348 94.5197 184.889 102.39 194.273 104.58C203.663 106.764 223.521 110.719 231.191 112.501C238.86 114.283 245.016 115.461 245.016 115.461C245.228 115.484 245.424 115.495 245.597 115.495C246.915 115.495 247.233 114.925 247.697 114.367C248.323 113.618 248.602 112.992 248.021 111.294C246.898 108.591 241.173 102.279 233.297 96.4357C225.42 90.5928 175.655 53.4743 164.321 45.0618C152.988 36.655 146.368 34.0352 143.296 33.4319C142.659 33.309 142.151 33.2532 141.726 33.2532L141.732 33.2588Z" fill="url(#paint32_linear_38479_43706)"/>
</g>
<defs>
<linearGradient id="paint0_linear_38479_43706" x1="67.0425" y1="138.146" x2="169.449" y2="213.081" gradientUnits="userSpaceOnUse">
<stop stop-color="#FDA1FF"/>
<stop offset="1" stop-color="#97C5FF"/>
</linearGradient>
<linearGradient id="paint1_linear_38479_43706" x1="154.596" y1="107.585" x2="133.722" y2="142.285" gradientUnits="userSpaceOnUse">
<stop offset="0.49" stop-color="#B78EFA"/>
<stop offset="1" stop-color="#8F6CCD"/>
</linearGradient>
<linearGradient id="paint2_linear_38479_43706" x1="86.9898" y1="141.391" x2="149.848" y2="251.624" gradientUnits="userSpaceOnUse">
<stop offset="0.2" stop-color="#FDA1FF"/>
<stop offset="0.3" stop-color="#F3A4FF"/>
<stop offset="0.48" stop-color="#D9ADFF"/>
<stop offset="0.71" stop-color="#AFBCFF"/>
<stop offset="0.83" stop-color="#97C5FF"/>
</linearGradient>
<radialGradient id="paint3_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(147.657 140.865) rotate(53.1) scale(13.5939 0.815268)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint4_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(155.226 134.992) rotate(53.1) scale(13.5939 3.80654)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<linearGradient id="paint5_linear_38479_43706" x1="90.0845" y1="133.113" x2="127.896" y2="270.281" gradientUnits="userSpaceOnUse">
<stop stop-color="#EEBEFF"/>
<stop offset="1" stop-color="#79EDFF"/>
</linearGradient>
<linearGradient id="paint6_linear_38479_43706" x1="215.796" y1="132.476" x2="193.893" y2="229.152" gradientUnits="userSpaceOnUse">
<stop stop-color="#00B99A"/>
<stop offset="1" stop-color="#009CBD"/>
</linearGradient>
<linearGradient id="paint7_linear_38479_43706" x1="214.137" y1="123.494" x2="176.426" y2="239.804" gradientUnits="userSpaceOnUse">
<stop stop-color="#00CC9E"/>
<stop offset="0.22" stop-color="#00884A"/>
<stop offset="0.31" stop-color="#008D64"/>
<stop offset="0.55" stop-color="#009A9D"/>
<stop offset="0.75" stop-color="#00A3C7"/>
<stop offset="0.91" stop-color="#00A8E1"/>
<stop offset="1" stop-color="#00ABEB"/>
</linearGradient>
<linearGradient id="paint8_linear_38479_43706" x1="188.285" y1="127.583" x2="219.393" y2="199.323" gradientUnits="userSpaceOnUse">
<stop stop-color="#3CE6AC"/>
<stop offset="1" stop-color="#00E3FF"/>
</linearGradient>
<radialGradient id="paint9_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(196.903 118.263) scale(22.3021 22.3021)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint10_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(197.828 124.408) scale(5.58119)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<linearGradient id="paint11_linear_38479_43706" x1="171.198" y1="181.174" x2="254.819" y2="181.174" gradientUnits="userSpaceOnUse">
<stop stop-color="#00E4FF"/>
<stop offset="1" stop-color="#00E3F7"/>
</linearGradient>
<linearGradient id="paint12_linear_38479_43706" x1="68.7964" y1="53.1727" x2="91.2742" y2="118.461" gradientUnits="userSpaceOnUse">
<stop stop-color="#00CDC2"/>
<stop offset="1" stop-color="#288822"/>
</linearGradient>
<linearGradient id="paint13_linear_38479_43706" x1="68.8914" y1="53.4464" x2="91.2798" y2="118.478" gradientUnits="userSpaceOnUse">
<stop stop-color="#00CDC2"/>
<stop offset="1" stop-color="#288822"/>
</linearGradient>
<linearGradient id="paint14_linear_38479_43706" x1="68.5729" y1="53.2117" x2="90.4698" y2="116.796" gradientUnits="userSpaceOnUse">
<stop stop-color="#00CDC3"/>
<stop offset="1" stop-color="#4FDB5E"/>
</linearGradient>
<radialGradient id="paint15_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(135.831 92.6318) scale(58.2057)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint16_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(142.36 85.1002) rotate(96.41) scale(24.117 2.34693)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<linearGradient id="paint17_linear_38479_43706" x1="73.7846" y1="73.282" x2="94.1286" y2="124.092" gradientUnits="userSpaceOnUse">
<stop stop-color="#00CDC3"/>
<stop offset="1" stop-color="#4FDB5E"/>
</linearGradient>
<radialGradient id="paint18_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(198.277 71.1581) scale(37.5635 37.5635)">
<stop stop-color="#88D2FF"/>
<stop offset="1" stop-color="#0079FF"/>
</radialGradient>
<radialGradient id="paint19_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(188.638 76.0921) scale(53.2287 53.2287)">
<stop stop-color="#88D2FF"/>
<stop offset="1" stop-color="#0079FF"/>
</radialGradient>
<linearGradient id="paint20_linear_38479_43706" x1="170.125" y1="83.9512" x2="214.941" y2="64.406" gradientUnits="userSpaceOnUse">
<stop offset="0.04" stop-color="#62C7FF"/>
<stop offset="0.79" stop-color="#D9B5FF"/>
</linearGradient>
<linearGradient id="paint21_linear_38479_43706" x1="185.487" y1="73.8574" x2="222.756" y2="88.1797" gradientUnits="userSpaceOnUse">
<stop stop-color="#C07DFF" stop-opacity="0"/>
<stop offset="1" stop-color="#A855F5"/>
</linearGradient>
<radialGradient id="paint22_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(162.835 63.273) rotate(61.84) scale(22.3734 2.79939)">
<stop stop-color="#0079FF"/>
<stop offset="1" stop-color="#0079FF"/>
</radialGradient>
<radialGradient id="paint23_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(131.761 58.5752) rotate(64.3) scale(24.7035 1.47971)">
<stop stop-color="#0079FF"/>
<stop offset="1" stop-color="#0079FF" stop-opacity="0"/>
</radialGradient>
<linearGradient id="paint24_linear_38479_43706" x1="200.362" y1="77.0133" x2="251.942" y2="90.8497" gradientUnits="userSpaceOnUse">
<stop stop-color="#0079FF"/>
<stop offset="1" stop-color="#0079FF" stop-opacity="0.5"/>
</linearGradient>
<radialGradient id="paint25_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(214.954 102.925) rotate(13.66) scale(30.6182 0.612498)">
<stop stop-color="#CDA2FD"/>
<stop offset="1" stop-color="#0079FF" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint26_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(181.034 112.951) rotate(20.22) scale(10.6772 1.81487)">
<stop offset="0.11" stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint27_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(154.157 89.1055) rotate(33.25) scale(15.206 4.33106)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint28_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(181.034 112.951) rotate(20.22) scale(10.6772 1.81487)">
<stop offset="0.11" stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint29_radial_38479_43706" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(216.335 100.866) rotate(13.89) scale(32.1943 1.34649)">
<stop stop-color="#0079FF"/>
<stop offset="1" stop-color="#0079FF" stop-opacity="0"/>
</radialGradient>
<linearGradient id="paint30_linear_38479_43706" x1="139.034" y1="74.2205" x2="247.96" y2="74.2205" gradientUnits="userSpaceOnUse">
<stop stop-color="#88D2FF"/>
<stop offset="1" stop-color="#F6B6FF"/>
</linearGradient>
<linearGradient id="paint31_linear_38479_43706" x1="173.281" y1="92.1402" x2="194.972" y2="72.8631" gradientUnits="userSpaceOnUse">
<stop stop-color="#0079FF"/>
<stop offset="1" stop-color="#0079FF" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint32_linear_38479_43706" x1="139" y1="74.3768" x2="248.697" y2="74.3768" gradientUnits="userSpaceOnUse">
<stop stop-color="#88D2FF"/>
<stop offset="1" stop-color="#F6B6FF"/>
</linearGradient>
<clipPath id="clip0_38479_43706">
<rect width="286" height="286" fill="white"/>
</clipPath>
</defs>
</svg>


path: references/asset-routing.md
content: # Asset Handling — The Classification Engine

When the user provides files, URLs, or references, route each asset to the right path. The user should NEVER have to think about this.

## Two Paths

| Path | What happens | When to use |
|------|-------------|-------------|
| **A: Contextualize → Prompt** | Read/analyze the asset, extract key info, bake into script. Video Agent never sees the original. | Reference material, auth-walled content, documents where the *information* matters more than the *visual*. |
| **B: Attach to API** | Upload the raw file via `files[]`. Video Agent analyzes, extracts graphics, uses as frames/B-roll. | Screenshots, branded assets, PDFs with important visual layouts, images the viewer should literally see. |
| **A+B: Both** | Contextualize for script quality AND attach for visual use. | Long docs where you need to summarize but Video Agent should also have the full source. |

## Classification Flow

```
1. Can Video Agent access this directly?
   - Public URL (no auth, no paywall) → YES
   - Private/internal URL → NO
   - Local file → NO (must upload first)

2. Should the viewer SEE this asset?
   - Screenshot, logo, product image, chart → YES → Path B
   - Research doc, article, context material → NO → Path A
   - Ambiguous → Path A+B

3. Is the content too long for the prompt?
   - Short (< 500 words) → fits in prompt
   - Long (> 500 words) → summarize key points, attach full doc
```

## Decision Matrix

| Asset Type | Publicly Accessible? | Show On Screen? | Route |
|-----------|---------------------|----------------|-------|
| Screenshot / image | N/A | Yes | **B: Attach** + describe in prompt as B-roll |
| Logo / brand asset | N/A | Yes | **B: Attach** + anchor to intro/outro |
| Public URL to file (PDF, image, video) | Yes | Maybe | **B: Download → upload via `/v3/assets` → pass `asset_id`** + summarize |
| Public URL to web page (HTML) | Yes | No | **A: Fetch and contextualize only.** Do NOT pass HTML URLs in `files[]`. |
| Auth-walled URL (requires login) | No | No | **A: Ask the user to paste the content.** Never fabricate. |
| PDF (short, text-heavy) | N/A | No | **A+B: Extract key points** + attach |
| PDF (long, visual-rich) | N/A | Maybe | **B: Attach** + summarize top points |
| Raw data / spreadsheet | N/A | Partially | **A: Analyze and describe** key stats. Attach if charts should appear. |

## Executing Routes

### Path A (Contextualize)
- URLs: Use `web_fetch` to retrieve publicly accessible content
- For auth-walled content you cannot access: ask the user to paste the text directly
- Extract 3-5 most important points relevant to the video
- Weave naturally into the script. Don't dump. Integrate.

### Path B (Attach)
Upload to HeyGen:

**MCP:** upload via the asset tool (depends on environment).
**CLI:** `heygen asset create --file /path/to/file.png`

Max 32MB per file. Returns JSON with the new `asset_id`.

Or pass inline in `files[]`:
```json
{"type": "url", "url": "https://example.com/image.png"}
{"type": "asset_id", "asset_id": "<from upload>"}
{"type": "base64", "data": "<base64>", "content_type": "image/png"}
```

### Describe Asset Usage in Prompt
Be SPECIFIC:
- "Use the uploaded dashboard screenshot as B-roll when discussing analytics"
- "Display the company logo in the intro and end card"

### Log Classification
In the learning log entry, record:
```json
"assets_classified": [{"type": "image", "route": "attach", "accessible": true, "reason": "product screenshot"}]
```

## Rules

- **Never ask the user which path unless genuinely 50/50.** You're the producer. Make the call.
- **When in doubt, do both (A+B).** Over-providing costs nothing.
- **Always describe attached assets in the prompt.** Uploading without description = ignored.
- **Auth-walled content is YOUR job.** Bridge the gap between your access and Video Agent's.
- **URLs that fail:** Try `web_fetch`. If login/paywall/404 → tell the user, ask for content directly. Never silently fabricate.
- **HTML URLs cannot go in `files[]`.** Video Agent rejects `text/html`. Web pages are ALWAYS Path A only.
- **Prefer download→upload→asset_id** over `files[]{url}`. HeyGen's servers often blocked by CDN/WAF.


path: references/avatar-discovery.md
content: # Avatar Discovery & Voice Selection

## Path A: Discover Existing Avatars

### A1: Check for private avatars first

**If user specifies an avatar by name** (e.g. "use Eve's Podcast look"), take the fast path:

**MCP:** `list_avatar_looks(ownership=private)` — filter client-side by name match.
**CLI:**
```bash
heygen avatar looks list --ownership private --limit 50
```
Avoids the 2-call group→looks pattern.

**If user wants to browse**, use the group-first flow:

**MCP:**
1. `list_avatar_groups(ownership=private)` — list groups (each group = one person)
2. `list_avatar_looks(group_id=<group_id>)` — show looks for chosen group

**CLI:**
```bash
heygen avatar list --ownership private --limit 50
heygen avatar looks list --group-id <group_id> --limit 50
```

Each look has an `id` — this is the `avatar_id` you pass downstream.

Avatar types: `studio_avatar`, `video_avatar`, `photo_avatar`. Photo avatars support `motion_prompt` and `expressiveness`.

**ALWAYS show the preview image** when presenting an avatar look. Each look response includes `preview_image_url` — display inline.

### A2: Check last-used avatar

Check `heygen-video-log.jsonl` for last used avatar_id. If found:

**MCP:** `get_avatar_look(look_id=<look_id>)`
**CLI:** `heygen avatar looks get --look-id <look_id>`

Show preview image: "Last time you used [Avatar Name]. Use her again?"

### A3: Avatar conversation

Ask: "Do you want a visible presenter, or voice-over only?"

If voice-over only → no `avatar_id`. State in prompt: "Voice-over narration only."

If presenter wanted, present private avatars first. For public/stock avatars, browse by group:

**MCP:** `list_avatar_groups(ownership=public)`
**CLI:**
```bash
heygen avatar list --ownership public --limit 20
```

Show group names + one representative image. Let the user pick a person.

**MCP:** `list_avatar_looks(group_id=<group_id>)`
**CLI:**
```bash
heygen avatar looks list --group-id <group_id> --limit 10
```

**Why group-first:** The flat `heygen avatar looks list --ownership public` call returns 50+ results for only 3 unique people per page. Group-level browsing (2 calls) gives much better discovery UX.

### A4: Voice direction

After avatar is settled, confirm voice preferences (accent, delivery style, language).

**ALWAYS show a playable voice preview.** Each voice response includes `preview_audio_url` — share it.

**Handling missing/broken previews:** Some voices return bare `s3://` paths or `null`. When this happens: note "(no preview available)" and offer to generate a short TTS sample via `create_speech` (MCP) or `heygen voice speech create --text "<sample>" --voice-id <id> --input-type plain_text --language en --locale en-US` (CLI).

---

## Path B: Create a New Avatar

Two modes:

**Mode 1 — New character** (omit `avatar_group_id`): Creates a new person with their own group.
**Mode 2 — New look** (include `avatar_group_id`): Adds a variation to an existing character.

Always use Mode 2 when the avatar already exists and you're creating a variant (different outfit, orientation fix, bg change). Only use Mode 1 for genuinely new characters.

Three creation types:

**Photo avatar (from user's photo):**

**MCP:** `create_photo_avatar(name=<name>, file=<file_object>, avatar_group_id=<optional>)`
**CLI:**
```bash
heygen avatar create -d '{
  "type": "photo",
  "name": "My Avatar",
  "file": {"type": "url", "url": "https://example.com/headshot.jpg"},
  "avatar_group_id": "<optional>"
}'
```
Photo requirements: JPEG or PNG, min 512x512, clear front-facing face, good lighting.

**AI-generated avatar (from text prompt):**

**MCP:** `create_prompt_avatar(name=<name>, prompt=<appearance>, avatar_group_id=<optional>)`
**CLI:**
```bash
heygen avatar create -d '{
  "type": "prompt",
  "name": "Tech Presenter",
  "prompt": "Young professional woman, modern workspace, confident smile",
  "avatar_group_id": "<optional>"
}'
```
Prompt max: 1000 characters. Optional: up to 3 `reference_images`.

**Video avatar (from user's video recording):**

**MCP:** `create_digital_twin(name=<name>, file=<file_object>, avatar_group_id=<optional>)`
**CLI:**
```bash
heygen avatar create -d '{
  "type": "video",
  "name": "My Video Avatar",
  "file": {"type": "asset_id", "asset_id": "<uploaded_asset_id>"},
  "avatar_group_id": "<optional>"
}'
```

All three return `avatar_item` with `id` (look_id) and `group_id` — use `id` as `avatar_id` for videos.

Files: `{"type": "url", "url": "..."}`, `{"type": "asset_id", "asset_id": "..."}` (from `heygen asset create --file <path>`), or `{"type": "base64", "data": "...", "content_type": "..."}`.

---

## Path C: Direct Image (Simplest for One-Off)

Skip avatar creation. Pass `image_url` directly:

**MCP:** `create_video_from_image(image_url=<url>, script=<script>, voice_id=<voice_id>, aspect_ratio="16:9")`
**CLI:**
```bash
heygen video create -d '{
  "image_url": "https://example.com/headshot.jpg",
  "script": "<script>",
  "voice_id": "<voice_id>",
  "aspect_ratio": "16:9"
}'
```
Also accepts `image_asset_id`. Fastest path for one-off talking-head video.

---

## Voice Selection

**MCP:** `list_voices(type=private)` then `list_voices(type=public, language=<lang>, gender=<gender>)`
**CLI:**
```bash
heygen voice list --type private --limit 20

# Public voices with filters
heygen voice list --type public --engine starfish --language en --gender female --limit 20
```

---

## How Avatar/Voice Are Passed

**MCP:** `create_video_agent(prompt=<prompt>, avatar_id=<look_id>, voice_id=<voice_id>, style_id=<optional>, orientation=<orientation>)`

**CLI:** `heygen video-agent create` with flags:
```bash
heygen video-agent create \
  --prompt "..." \
  --avatar-id "<look_id_from_discovery>" \
  --voice-id "<voice_id_from_discovery>" \
  --style-id "<optional_style_id>" \
  --orientation landscape
```

- **Custom/stock avatar with known ID** → pass `--avatar-id`. Do NOT describe avatar's appearance in prompt. Only delivery style + background/environment.
- **No avatar_id (auto-select)** → describe desired presenter in prompt. Less reliable (~80% vs ~97%).
- **Voice-over only** → omit `--avatar-id`, state in prompt.

> Always provide explicit `--avatar-id` for presenter videos. 97.6% duration accuracy vs ~80% without.


path: references/frame-check.md
content: # Frame Check — Aspect Ratio & Background Pre-Check

Runs automatically when `avatar_id` is set, before Generate. Appends correction notes to the Video Agent prompt. Does NOT generate images or create new looks.

## Step 1: Fetch the avatar look metadata

**MCP:** `get_avatar_look(look_id=<avatar_id>)`
**CLI:** `heygen avatar looks get --look-id <avatar_id>`

Extract:
- `avatar_type`: `"photo_avatar"` | `"studio_avatar"` | `"video_avatar"`
- `preview_image_url`: use to determine orientation
- `image_width` and `image_height`: use for orientation calculation

## Step 2: Determine avatar orientation

Use `image_width` and `image_height` from the API response (or fetch the preview image dimensions if those fields are missing).
- width > height → landscape avatar
- height > width → portrait avatar
- width == height → **square avatar** (1:1) → always needs framing correction
- Fetch fails or no preview → assume portrait (safer default)

## Step 3: Determine if background exists

| `avatar_type` | Background? | Reason |
|---|---|---|
| `photo_avatar` | ✅ Handled by Video Agent | Video Agent generates avatar + environment together during video creation. No standalone bg correction needed. |
| `studio_avatar` | ⚠️ Maybe | Check preview image — if transparent/solid/empty → "No background" → apply Correction C |
| `video_avatar` | ✅ Yes | Recorded in a real environment |

## Step 4: Append correction notes to prompt

Based on Steps 2-3, append zero or more correction notes **verbatim to the end of the Video Agent prompt text.** Do NOT ask the user. Do NOT generate images. Do NOT create new looks.

### A) Portrait avatar → Landscape video (most common)

```
FRAMING NOTE: The selected avatar image is in portrait orientation but this video is landscape (16:9). Frame the presenter from the chest up, centered in the landscape canvas. Use AI Image tool to generative fill to extend the scene horizontally with a complementary background environment that matches the video's tone (studio, office, or contextually appropriate setting). Do NOT add black bars or pillarboxing. The avatar should feel natural in the 16:9 frame.
```

### B) Landscape avatar → Portrait video

```
FRAMING NOTE: The selected avatar image is in landscape orientation but this video is portrait (9:16). Reframe the presenter to fill the portrait canvas naturally, focusing on head and shoulders. Use AI Image tool to generative fill to extend vertically if needed. Do NOT add letterboxing. The avatar should fill the portrait frame comfortably.
```

### D) Square avatar → Landscape video

```
FRAMING NOTE: The selected avatar image is in square (1:1) orientation but this video is landscape (16:9). Frame the presenter from the chest up, centered in the landscape canvas. Use AI Image tool to generative fill to extend the scene horizontally with a complementary background environment that matches the video's tone (studio, office, or contextually appropriate setting). Do NOT add black bars or pillarboxing. The avatar should feel natural in the 16:9 frame.
```

### E) Square avatar → Portrait video

```
FRAMING NOTE: The selected avatar image is in square (1:1) orientation but this video is portrait (9:16). Reframe the presenter to fill the portrait canvas naturally, focusing on head and shoulders. Use AI Image tool to generative fill to extend vertically if needed. Do NOT add letterboxing. The avatar should fill the portrait frame comfortably.
```

### C) Missing background — studio_avatar only

**Only for `studio_avatar` with transparent/solid/empty background. NOT for photo_avatar** (Video Agent handles photo_avatar environments during generation).

```
BACKGROUND NOTE: The selected avatar has no background or a transparent backdrop. Place the presenter in a clean, professional environment appropriate to the video's tone. For business/tech content: modern studio with soft lighting and subtle depth. For casual content: bright, minimal space with natural light. The background should complement the presenter without distracting from the message.
```

## Correction Stacking Matrix

Corrections can stack. Use the matrix to determine which notes to append.

| avatar_type | Orientation Match? | Has Background? | Corrections |
|---|---|---|---|
| `video_avatar` | ✅ matched | ✅ Yes | None |
| `video_avatar` | ❌ mismatched | ✅ Yes | Framing only (A or B) |
| `video_avatar` | ◻ square | ✅ Yes | Framing only (D or E) |
| `studio_avatar` | ✅ matched | ✅ Yes (check preview) | None |
| `studio_avatar` | ✅ matched | ❌ No | Background (C) |
| `studio_avatar` | ❌ mismatched | ✅ Yes | Framing only (A or B) |
| `studio_avatar` | ❌ mismatched | ❌ No | Framing (A or B) + Background (C) |
| `studio_avatar` | ◻ square | ✅ Yes | Framing only (D or E) |
| `studio_avatar` | ◻ square | ❌ No | Framing (D or E) + Background (C) |
| `photo_avatar` | ✅ matched | (n/a) | **None** — Video Agent handles avatar + environment together |
| `photo_avatar` | ❌ mismatched | (n/a) | **Framing only (A or B)** |
| `photo_avatar` | ◻ square | (n/a) | **Framing only (D or E)** |

**How to check if studio_avatar has a background:** Fetch `preview_image_url`. If transparent/checkered, solid color, or cutout → "No background" → append Correction C.

**photo_avatar rule:** Video Agent generates the avatar and its environment together during video creation. Do NOT append Correction C for photo_avatars. Only append framing corrections (A, B, D, or E) if there's an orientation mismatch.

## Step 5: Submit with original avatar_id

After appending correction notes to the prompt, submit the video request using the **original `avatar_id`** (unchanged). Video Agent handles framing and background internally based on the FRAMING NOTE and BACKGROUND NOTE directives in the prompt.

## Step 6: Log the correction

Add to learning log entry:
- `"aspect_correction"`: `"portrait_to_landscape"` | `"landscape_to_portrait"` | `"square_to_landscape"` | `"square_to_portrait"` | `"background_fill"` | `"both"` | `"none"`
- `"avatar_type"`: the raw value from the API


path: references/motion-vocabulary.md
content: ---
name: motion-vocabulary
description: Motion verbs, the 5-layer visual system, scene types, and anti-patterns for Video Agent prompts
---

# Motion Vocabulary & Visual Layer System

Video Agent is an HTML interpreter. It renders layouts, typography, and structured content natively. The key to great B-roll: describe elements with **action verbs** ("slams in," "types on," "counts up") not layout specs ("upper-left, 48pt").

Based on patterns from 40+ produced videos.

> **Language note:** Motion verbs MUST remain in English regardless of the video's content language. Video Agent's rendering engine responds to these specific English verbs. Do not translate "SLAMS", "CASCADE", "COUNTS UP", etc. They are API-level commands, not viewer-facing text.

## Motion Verbs

Use these exact verbs in prompts. Video Agent responds to them. Without them, you get static frames.

### High Energy
| Verb | Example |
|------|---------|
| **SLAMS** | `"$95M" SLAMS in from left at -5 degrees` |
| **CRASHES** | `Title CRASHES in from right, screen-shake on impact` |
| **PUNCHES** | `Quote card PUNCHES up from bottom` |
| **STAMPS** | `Data blocks STAMP in staggered 0.4s` |
| **SHATTERS** | `Text SHATTERS after 1.5s, revealing number underneath` |

### Medium Energy
| Verb | Example |
|------|---------|
| **CASCADE** | `Three cards CASCADE from top, staggered 0.3s` |
| **SLIDES** | `Ticker SLIDES in from right — continuous scroll` |
| **DROPS** | `"TIER 1" DROPS in with white flash` |
| **FILLS** | `Progress bar FILLS 0 to 90% in orange` |
| **DRAWS** | `Chart line DRAWS itself left to right` |

### Low Energy
| Verb | Example |
|------|---------|
| **types on** | `Quote types on word by word in italic white` |
| **fades in** | `Logo fades in at center, held for 3 seconds` |
| **FLOATS** | `Bokeh orbs FLOAT across frame at different speeds` |
| **morphs** | `Number morphs from 17 to 18.9` |
| **COUNTS UP** | `"1.85M" COUNTS UP from 0 in amber 96pt` |

## Transition Types

| Transition | Energy | Best With Styles |
|------------|--------|-----------------|
| Smash cut | Aggressive | Deconstructed, Maximalist, Carnival Surge |
| White flash frame | Punchy | Deconstructed, Maximalist |
| Grid wipe | Systematic | Swiss Pulse, Digital Grid |
| Hard cut | Clean | Swiss Pulse, Shadow Cut |
| Liquid dissolve | Elegant | Data Drift, Dream State |
| Slow cross-dissolve | Refined | Velvet Standard |
| Pop cut / bounce | Fun | Play Mode, Carnival Surge |
| Snap cut | Urgent | Red Wire, Contact Sheet |
| Soft dissolve | Warm | Soft Signal, Warm Grain, Quiet Drama |
| Iris wipe | Nostalgic | Heritage Reel |

## The 5-Layer Visual System

Break B-roll scenes into 5 stacked layers. This is the most powerful technique for motion graphics.

| Layer | Purpose | Examples |
|-------|---------|---------|
| **L1** | Background | Textured surface, grid, gradient, color field |
| **L2** | Hero content | Main headline/number that dominates the frame |
| **L3** | Supporting data | Cards, stats, bullet points, secondary information |
| **L4** | Information bar | Tickers, labels, source attributions, quotes |
| **L5** | Effects | Particles, glitches, grid animations, ambient motion |

**Rules:**
- Every B-roll scene: 4+ layers minimum
- Every overlay content side: 3+ layers minimum
- **Every element must MOVE.** No static frames.

### Example: B-Roll Scene with Layers

```
SCENE 2 — FULL SCREEN B-ROLL (12s)
[NO AVATAR — motion graphic only]
VOICEOVER: "One-point-eight-five million signups. Twenty-eight percent month over month."
LAYER 1: Dark #1a1a1a background with thin grid lines pulsing at 8% opacity.
LAYER 2: "1.85M" SLAMS in from left, white Bold 140pt. "+28% MoM" appears in amber.
LAYER 3: Three stat cards CASCADE from top-right, staggered 0.3s.
         Each number COUNTS UP from 0.
LAYER 4: Bottom ticker scrolls: "Non-brand search +36% • Brand impressions 9.2M"
LAYER 5: Grid lines RIPPLE outward on "1.85M" slam.
Hard cut.
```

## Scene Types

| Type | Format | When to Use |
|------|--------|-------------|
| **A-ROLL** | Avatar speaking to camera | Intros, key insights, CTAs, emotional beats |
| **FULL SCREEN B-ROLL** | No avatar, motion graphics only | Data visualization, information-dense content |
| **A-ROLL + OVERLAY** | Split frame: avatar + content | Presenting data while maintaining human connection |

**Rotation is mandatory.** Never 3+ of the same type in a row. Every video needs at least 2 pure B-roll scenes.

**Voiceover on EVERY scene.** Every B-roll scene MUST include a `VOICEOVER:` line. Silent B-roll = broken video.

## Timing Guidelines

| Content Type | Duration |
|---|---|
| Hook/Intro (A-roll) | 6-10 seconds |
| Data-heavy B-roll | 10-15 seconds (NEVER ≤5s — causes black frames) |
| A-roll + Overlay | 8-12 seconds |
| CTA / Close (A-roll) | 6-8 seconds |

**Common video lengths:**
- Social clip: 30-45s (5-7 scenes)
- Briefing: 60-75s (7-9 scenes)
- Deep dive: 90-120s (10-13 scenes)

## Avatar Description Guide

**The avatar is NOT a fixed headshot.** Design it for each video like a movie character.

### Thematic Wardrobe Rule

The avatar's outfit and environment MUST match the content's emotional/cultural context:

| Content Type | Avatar Design | NOT This |
|---|---|---|
| Breaking tech news | Field reporter, windswept hair, earpiece, city skyline | "Anchor at a desk" |
| Data analysis | Black merino turtleneck, minimalist desk, dual monitors with charts | "Business casual" |
| Product launch | Branded tee, open-plan startup space, product prototype on desk | "Generic office" |
| Tutorial | Casual hoodie, messy developer desk, sticky notes, coffee mug | "Presenter in a studio" |

### What to Specify

| Element | Weak | Strong |
|---|---|---|
| Clothing | "Business casual" | "Black ribbed merino turtleneck, high collar framing jaw" |
| Environment | "An office" | "Glass-walled conference room. Whiteboard with hand-drawn tier pyramid" |
| Monitor content | "Computer screens" | "Monitor shows scrolling green terminal text and red security alerts" |
| Lighting | "Well lit" | "Cool blue monitor glow from left, warm amber desk lamp from right" |

### Template (60-100 words)
```
AVATAR: [Clothing — fabric, color, fit, accessories, posture].
[Setting — specific props, brand logos, what's on the walls].
[Monitors/desk — content visible on screens, items on desk].
[Lighting — direction, color temperature]. [Mood of the space].
```

**Remember:** When `avatar_id` is set as an API parameter, do NOT describe appearance. Only delivery style and environment notes. Say "The selected presenter" instead.

## Critical On-Screen Text

List every piece of text that MUST appear literally on screen:

```
CRITICAL ON-SCREEN TEXT (display literally):
- "$141M ARR — All-Time High"
- "1.85M Signups — +28% MoM"
- Quote: "Use technology to serve the message, not distract from it." — Shalev Hani
- "@eve_builds" — exact social handle
```

Without this block, Video Agent will summarize, round numbers, or rephrase quotes.

**Voiceover number rule:** Spell out numbers in speech ("one-point-eight-five million"), use figures on screen ("1.85M").

## What Doesn't Work

Patterns that consistently produce poor results (from 40+ videos):

**Layout language** — Screen coordinates cause empty/black B-roll:
```
❌ "UPPER-LEFT: headline in 48pt Helvetica"
❌ "CENTER-SCREEN: display at coordinates (400, 300)"
✅ "135K" SLAMS in from left, white Impact 120pt, fills 40% of frame.
```

**Named artists without specs** — "Ikko Tanaka style" means nothing to Video Agent. Translate to concrete rules:
```
❌ "Use an Ikko Tanaka style"
✅ "Flat color blocks, maximum 3 colors per frame, 60% negative space, typography as primary element"
```

**Style examples injected into prompts** — Full example scenes from a style library confuse the agent. Use the style's **rules**, not example scenes.

**Forced short B-roll (≤5 seconds)** — Too short for rendering. Every tested video with 5s B-roll had empty/black screens. Minimum 10s.

**Content as a list, not a story** — "Here are 5 tweets" produces flat videos. Always synthesize a thesis: *"X is happening because Y — here's the proof."*

**Static frames** — Every element must have a motion verb. "Title appears" → dead frame. "Title SLAMS in from left" → alive.


path: references/official-prompt-guide.md
content: # HeyGen Video Agent — Official Prompt Guide (Complete)
Source: https://www.notion.so/heygen/Video-Agent-Prompt-Guide-2e6449792c69801d9353c885aad92c9e

## Core Philosophy
"Video Agent isn't magic; it's a production partner that executes your creative direction."
"The more specific you are about content, style, media types, and scene structure, the closer you'll get to exactly what you envision."

## Three UI Controls
1. **Avatar** — select specific avatar, Auto mode, or "no avatar" for voice-over only (MUST explicitly say "no avatar" in prompt)
2. **Duration** — 30s, 1min, 2min, or Auto (agent follows prompt/script for length, not forced)
3. **Aspect Ratio** — Portrait or Landscape, or Auto

## Prompting Hierarchy (Basic → Advanced)

### Level 1: Basic Prompt
Describe the content you want delivered:
- "Introduce HeyGen to knowledge workers, talk about its Talking Avatar models"
- "Make a compliance training video and explain phishing in detail"

### Level 2: Script-Driven (STRONGLY RECOMMENDED)
Paste a full video script. Agent follows scene-by-scene while improving flow, timing, and visuals.
This is "the single biggest upgrade most people miss."

### Level 3: Scene-by-Scene (Maximum Control)
```
Scene 1: [Scene Type]
  Visual: [Describe exact visual]
  VO/Script: "[What the avatar says]"
  Duration: [Approximate length]
```

## Attachments
- Images, videos, product screenshots, diagrams
- PDFs, documents (agent extracts key info)
- Upload own photo → agent uses as talking avatar
- ALWAYS add context: "Use the attached screenshots as B-roll when discussing features"

## The "Catchall" Style Block (Personal Favorite of HeyGen Team)
```
Use minimal, clean styled visuals. Blue, black, and white as main colors.
Leverage motion graphics as B-rolls and A-roll overlays. Use AI videos when necessary.
When real-world footage is needed, use Stock Media.
Include an intro sequence, outro sequence, and chapter breaks using Motion Graphics.
```

## Style Descriptor Presets
| Style | Best For | Prompt Addition |
|-------|----------|-----------------|
| Minimalistic | Corporate, Tech, SaaS | "Use minimalistic, clean visuals with lots of white space" |
| Cartoon/Animated | Education, Kids content | "Use cartoon-style illustrated visuals" |
| Bold & Vibrant | Marketing, Social | "Use bold, vibrant colors and dynamic visuals" |
| Cinematic | Brand films, High-end | "Use cinematic quality visuals with dramatic lighting" |
| Flat Design | Modern, App demos | "Use flat design style with geometric shapes" |
| Gradient Modern | Tech, Startup | "Use modern gradient backgrounds and sleek transitions" |
| Retro/Vintage | Nostalgia, Creative | "Use retro-inspired visuals with warm tones" |

## Color Specification
- Exact hex codes: "Use #1E40AF as primary blue, #F8FAFC as background white, #0F172A for text"
- Brand colors: "Stick to our brand colors: coral (#FF6B6B), navy (#2C3E50), cream (#FFF5E6)"
- Font families: "Use Inter font family throughout"
- WHY: Without defined style, visuals look inconsistent scene-to-scene

## Media Types

### Motion Graphics
Animated text, icons, charts, shapes, transitions.
- A-roll overlays: lower thirds, bullet points, animated callouts
- B-roll scenes: animated explanations, data viz, process flows
- Chapter cards: section breaks, intros, outros
- Information display: statistics, comparisons, timelines

### AI-Generated Images & Videos
- Conceptual illustrations, abstract concepts
- Custom scenarios stock can't cover
- Stylized visuals in particular artistic style
- Product mockups in various contexts

### Stock Media
Real-world footage from stock libraries.
- Authentic scenes (offices, cities, people)
- Industry-specific (medical, manufacturing, retail)
- Emotional moments, human connection
- Establishing shots, locations

### Media Type Decision Matrix
| Content Type | Motion Graphics | AI Generated | Stock Media |
|---|---|---|---|
| Data/Statistics | ✅ Best | ❌ | ❌ |
| Abstract Concepts | ✅ Good | ✅ Best | ❌ |
| Real Environments | ❌ | ⚠️ Can work | ✅ Best |
| Brand Elements | ✅ Best | ❌ | ❌ |
| Human Emotions | ❌ | ⚠️ Uncanny | ✅ Best |
| Custom Scenarios | ⚠️ Limited | ✅ Best | ⚠️ May not exist |
| Technical Diagrams | ✅ Best | ❌ | ❌ |

## Example Prompts (Steal These)

### Compliance Training
"Use a professional female avatar. Make a compliance training video explaining phishing in detail. Use examples and list top watch-outs. Leverage motion graphics as A-roll overlay and B-roll to help explain core concepts."

### Educational Explainer (Voice-Over Only)
"Create a 1-minute video about camera aperture. Use minimal science diagrams and visualizations. No avatar needed, only voice-over. Cool neutrals (navy, cyan), thin-line diagrams, and slow elegant motion. B-roll is abstract scientific illustrations. Sequencing: definition → diagram expansion → conceptual layering, with fade-through transitions."

### Brand Story (Animated)
"Make a video telling the story of how Twitch got started. Use cartoon-style animations and overlays. I want Twitch's iconic colors and fonts. Use motion graphics overlays and AI-generated B-roll."

## Community Pro Tips

### Stack style instructions at the end
Put content/script first, then add all style directives (colors, motion graphics preferences, media type guidance) as a block at the bottom. Keeps creative intent clean and technical specs organized.

### Save your catchall as a template
If you find a style combo that works, reuse it across all videos. Consistency builds brand recognition.

### Iterate in conversation
Video Agent remembers context within a session. After first render: "make the intro shorter" or "swap the B-roll in scene 3 for stock footage" without re-prompting everything.


path: references/prompt-craft.md
content: # Prompt Craft Reference

Production-quality prompt engineering for HeyGen Video Agent. Combines official HeyGen guidance with patterns validated across 80+ test videos.

Load this when the user wants cinematic/polished output, scene-by-scene control, or specific visual styles.

---

## Prompting Levels (from HeyGen Official Guide)

### Level 1: Basic
Just describe content. Video Agent fills in the rest.
```
"Introduce HeyGen to knowledge workers, talk about its Talking Avatar models"
```

### Level 2: Script-Driven (RECOMMENDED DEFAULT)
Paste a full video script. Agent follows scene-by-scene while improving flow, timing, and visuals.
This is "the single biggest upgrade most people miss." — HeyGen docs

### Level 3: Scene-by-Scene (Maximum Control)
```
Scene 1: [Scene Type]
  Visual: [Describe exact visual]
  VO/Script: "[What the avatar says]"
```

**Official recommendation:** Don't assign per-scene timestamps. Natural flow + tone description outperforms rigid scene structure.

---

## Prompt Anatomy (Production Quality)

```
FORMAT:    What kind of video, how long, what energy
TONE:      Emotional register, references
AVATAR:    "The selected presenter" (when avatar_id set) or delivery style
STYLE:     Colors, typography, motion rules, transitions (see Style Block)
CRITICAL ON-SCREEN TEXT:  Exact strings that must appear literally
SCENE-BY-SCENE:  (if >60s) Individual scene breakdowns with VO and visual type
MUSIC:     Genre, energy arc
```

**Rule: Content/script first, style block at the end.** Keeps creative intent clean and technical specs organized.

### Critical On-Screen Text

List every exact string. Without this, Video Agent rephrases, summarizes, or rounds numbers.

```
CRITICAL ON-SCREEN TEXT (display literally):
- "$141M ARR — All-Time High"
- "1.85M Signups — +28% MoM"
- Quote: "Use technology to serve the message." — Shalev Hani
```

---

## Style Block

Every prompt should end with a style block. Without one, visuals look inconsistent scene-to-scene.

### The HeyGen Catchall (official team recommendation)
```
Use minimal, clean styled visuals. Blue, black, and white as main colors.
Leverage motion graphics as B-rolls and A-roll overlays. Use AI videos when necessary.
When real-world footage is needed, use Stock Media.
Include an intro sequence, outro sequence, and chapter breaks using Motion Graphics.
```

### Style Presets (from HeyGen docs)

| Style | Best For | Prompt Language |
|-------|----------|-----------------|
| Minimalistic | Corporate, Tech, SaaS | "Use minimalistic, clean visuals with lots of white space" |
| Cartoon/Animated | Education, Kids | "Use cartoon-style illustrated visuals" |
| Bold & Vibrant | Marketing, Social | "Use bold, vibrant colors and dynamic visuals" |
| Cinematic | Brand films, High-end | "Use cinematic quality visuals with dramatic lighting" |
| Flat Design | Modern, App demos | "Use flat design style with geometric shapes" |
| Gradient Modern | Tech, Startup | "Use modern gradient backgrounds and sleek transitions" |
| Retro/Vintage | Nostalgia, Creative | "Use retro-inspired visuals with warm tones" |

### Brand Colors

Be explicit with hex codes and fonts:
```
Use #1E40AF as primary blue, #F8FAFC as background white, #0F172A for text.
Font: Inter family throughout.
```

Without defined colors, visuals look inconsistent scene-to-scene.

---

## Media Types & When to Use Each

Video Agent supports three media types. Guide it explicitly or it guesses (often wrong).

### Motion Graphics
Animated text, icons, charts, shapes, transitions.
- **A-roll overlays:** lower thirds, bullet points, animated callouts
- **B-roll scenes:** animated explanations, data viz, process flows
- **Chapter cards:** section breaks, intros, outros
- **Best for:** Data, statistics, brand elements, technical diagrams

### AI-Generated Images & Videos
- Conceptual illustrations, abstract concepts
- Custom scenarios stock can't cover
- Stylized visuals in particular artistic style
- **Best for:** Abstract concepts, custom scenarios, product mockups

### Stock Media
Real-world footage from stock libraries.
- Authentic scenes (offices, cities, people)
- Industry-specific (medical, manufacturing, retail)
- **Best for:** Real environments, human emotions, establishing shots

### Decision Matrix

| Content Type | Motion Graphics | AI Generated | Stock Media |
|---|---|---|---|
| Data/Statistics | ✅ Best | ❌ | ❌ |
| Abstract Concepts | ✅ Good | ✅ Best | ❌ |
| Real Environments | ❌ | ⚠️ Can work | ✅ Best |
| Brand Elements | ✅ Best | ❌ | ❌ |
| Human Emotions | ❌ | ⚠️ Uncanny | ✅ Best |
| Custom Scenarios | ⚠️ Limited | ✅ Best | ⚠️ May not exist |
| Technical Diagrams | ✅ Best | ❌ | ❌ |

---

## Scene Types

| Type | Format | When |
|------|--------|------|
| **A-ROLL** | Avatar speaking to camera | Intros, key insights, CTAs, emotional beats |
| **FULL SCREEN B-ROLL** | No avatar, motion graphics only | Data visualization, info-dense content |
| **A-ROLL + OVERLAY** | Split frame: avatar + content | Presenting data while maintaining human connection |

**Rotation is mandatory.** Never 3+ of the same type in a row.

**Voiceover on EVERY scene.** Silent B-roll = broken video.

### Scene-by-Scene Template (HeyGen Official Format)

```
Scene 1: [Scene Type]
  Visual: [Describe exact visual — include media type]
  VO/Script: "[What the avatar says]"
```

### Detailed Scene Templates (validated in testing)

**A-ROLL:**
```
SCENE 1 — A-ROLL
[Avatar center-frame, excited, hands gesturing]
VOICEOVER: "The exact script for this scene."
Lower-third: "TITLE TEXT" white on blue bar.
```

**B-ROLL with layered motion:**
```
SCENE 2 — FULL SCREEN B-ROLL
[NO AVATAR — motion graphic only]
VOICEOVER: "The exact script for this scene."
Dark background with subtle grid. "HEADLINE" SLAMS in from left.
Three data cards CASCADE from right, staggered. Bottom ticker SLIDES in.
```

**A-ROLL + OVERLAY:**
```
SCENE 3 — A-ROLL + OVERLAY
[Avatar LEFT 35%. Content RIGHT 65%.]
VOICEOVER: "The exact script for this scene."
RIGHT SIDE: Stats COUNT UP below headline.
```

---

### Non-English Videos

The same prompt structure applies regardless of language:
1. **Script/narration:** In the video language
2. **Style block:** Always English (Video Agent directive)
3. **Motion verbs:** Always English (SLAMS, CASCADE, etc.)
4. **Critical on-screen text:** In whatever language should appear on screen
5. **Scene labels:** English (Scene 1, Scene 2) — structural, not rendered

---

## Example Prompts (from HeyGen Official Guide)

### Compliance Training
```
Use a professional female avatar. Make a compliance training video explaining phishing
in detail. Use examples and list top watch-outs. Leverage motion graphics as A-roll
overlay and B-roll to help explain core concepts.
```

### Educational Explainer (Voice-Over Only)
```
Create a 1-minute video about camera aperture. Use minimal science diagrams and
visualizations. No avatar needed, only voice-over. Cool neutrals (navy, cyan),
thin-line diagrams, and slow elegant motion. B-roll is abstract scientific
illustrations. Sequencing: definition → diagram expansion → conceptual layering.
```

### Brand Story (Animated)
```
Make a video telling the story of how Twitch got started. Use cartoon-style
animations and overlays. I want Twitch's iconic colors and fonts. Use motion
graphics overlays and AI-generated B-roll.
```

### Product Introduction (Japanese — non-English example)
```
日本のナレッジワーカー向けにHeyGenを紹介する1分間のビデオを作成してください。
トーキングアバターモデルの特徴を説明し、具体的な活用例を3つ含めてください。
ナレーターは選択されたプレゼンターが説明します。

CRITICAL ON-SCREEN TEXT (display literally):
- "HeyGen アバター V"
- "3分で動画作成"
- "API連携対応"

STYLE — SWISS PULSE (Müller-Brockmann): Black/white + electric blue #0066FF.
Grid-locked. Helvetica Bold. Animated counters. Diagonal accents.
Grid wipe transitions.
```

Note: Script content is in Japanese but STYLE block and scene labels remain in English — these are Video Agent directives, not viewer-facing content.

---

## Motion Vocabulary

Every visual element should have a motion verb. Static frames look dead.

### High Energy
- **SLAMS** — `"$95M" SLAMS in from left at -5 degrees`
- **CRASHES** — `Title CRASHES in from right, screen-shake on impact`
- **PUNCHES** — `Quote card PUNCHES up from bottom`

### Medium Energy
- **CASCADE** — `Three cards CASCADE from top, staggered 0.3s`
- **SLIDES** — `Ticker SLIDES in from right, continuous scroll`
- **FILLS** — `Progress bar FILLS 0 to 90% in orange`
- **DRAWS** — `Chart line DRAWS itself left to right`

### Low Energy
- **types on** — `Quote types on word by word in italic white`
- **fades in** — `Logo fades in at center, held 3 seconds`
- **COUNTS UP** — `"1.85M" COUNTS UP from 0 in amber`

---

## Pro Tips (from HeyGen community)

1. **Save your catchall as a template.** Find a style combo that works, reuse it. Consistency builds brand.
2. **Iterate in conversation.** Video Agent remembers context within a session. "Make the intro shorter" or "swap B-roll in scene 3 for stock footage" without re-prompting everything.
3. **Stack style at the end.** Content first, style directives last.
4. **Describe B-roll as motion verbs** ("slams in," "counts up"), NOT layout coordinates ("upper-left, 48pt").

---

## What Doesn't Work

- **Layout coordinates** — "upper-left: headline in 48pt" → blank frames. Use motion verbs.
- **Named artists without specs** — "Ikko Tanaka style" means nothing. Translate to colors + shapes + motion.
- **B-roll under 5 seconds** — Causes black/empty frames. 10s+ minimum.
- **Static elements** — Every element needs a motion verb.
- **Per-scene timestamps** — Makes delivery robotic (per HeyGen's own research). Use overall duration only.


path: references/prompt-styles.md
content: ---
name: prompt-styles
description: 20 named visual styles for Video Agent prompts — mood-first selection, copy-paste STYLE blocks
---

# Prompt Style Library

Named visual styles you inject directly into the prompt text. Each is inspired by a real graphic designer and tested across 40+ videos.

**These are different from HeyGen API styles (`style_id`).** API styles are curated templates on HeyGen's backend. Prompt styles give you full control over colors, typography, motion, and transitions directly in the prompt.

**How to use:** Pick a style. Copy the STYLE block. Paste it into the prompt after your script content.

**How to pick:** Match mood first, content second. Ask: *"What should the viewer FEEL?"*

> **Language note:** Style blocks stay in English regardless of the video's content language. They are technical directives to Video Agent's rendering engine, not viewer-facing text. The video's script and narration should be in the video language, but the STYLE block at the end is always English.

## Mood-to-Style Guide

| Content feels... | Use... |
|---|---|
| Personal, intimate | Soft Signal, Quiet Drama |
| Natural, earthy | Warm Grain, Earth Pulse |
| Nostalgic, historical | Heritage Reel |
| Data-driven, analytical | Swiss Pulse, Digital Grid |
| Elegant, premium | Velvet Standard, Geometric Bold |
| Cultural, global | Silk Route, Folk Frequency |
| Investigative, serious | Contact Sheet, Shadow Cut |
| Fun, lighthearted | Play Mode, Carnival Surge |
| Philosophical, abstract | Dream State |
| Punk, grassroots, raw | Deconstructed |
| Hype, loud, high-energy | Maximalist Type |
| Tech-forward, futuristic | Data Drift |
| Breaking, urgent | Red Wire |

## Quick Reference

| # | Style | Artist | Mood | Best For |
|---|---|---|---|---|
| 1 | Soft Signal | Sagmeister | Intimate, warm | Personal stories, wellness |
| 2 | Warm Grain | Eksell | Organic, friendly | Environmental, sustainability |
| 3 | Quiet Drama | Ray | Humanist, contemplative | Profiles, biographical |
| 4 | Heritage Reel | Cassandre | Nostalgic, vintage | History, retrospectives |
| 5 | Silk Route | Abedini | Flowing, mysterious | Global affairs, cross-cultural |
| 6 | Swiss Pulse | Müller-Brockmann | Clinical, precise | Data-heavy, analytical |
| 7 | Geometric Bold | Tanaka | Minimal, elegant | Lifestyle, visual essays |
| 8 | Velvet Standard | Vignelli | Premium, timeless | Luxury, investor updates |
| 9 | Digital Grid | Crouwel | Systematic, technical | Infrastructure, engineering |
| 10 | Contact Sheet | Brodovitch | Editorial, investigative | Journalism, deep dives |
| 11 | Folk Frequency | Terrazas | Cultural, vivid | Festivals, food, heritage |
| 12 | Earth Pulse | Ghariokwu | Grounded, communal | Community, grassroots |
| 13 | Dream State | Tomaszewski | Surreal, poetic | Op-eds, philosophy |
| 14 | Play Mode | Ahn Sang-soo | Playful, irreverent | Entertainment, pop culture |
| 15 | Carnival Surge | Lins | Euphoric, celebratory | Milestones, hype |
| 16 | Shadow Cut | Hillmann | Dark, cinematic | Exposés, investigations |
| 17 | Deconstructed | Brody | Industrial, raw | Tech news, punk energy |
| 18 | Maximalist Type | Scher | Loud, kinetic | Big announcements, launches |
| 19 | Data Drift | Anadol | Futuristic, immersive | AI/tech, innovation |
| 20 | Red Wire | Tartakover | Urgent, immediate | Breaking news, crisis |

## Production Performance (from 40+ videos)

| Rank | Style | Strength |
|------|-------|----------|
| 1 | Deconstructed (Brody) | Most reliable across all topics |
| 2 | Swiss Pulse (Müller-Brockmann) | Best for data-heavy content |
| 3 | Digital Grid (Crouwel) | Strong for tech topics |
| 4 | Geometric Bold (Tanaka) | Elegant and versatile |
| 5 | Maximalist Type (Scher) | High energy, use sparingly |

---

## Style Blocks (Copy-Paste Ready)

### 1. Soft Signal — Sagmeister
**Mood:** Intimate, warm | **Best for:** Personal stories, wellness
```
STYLE — SOFT SIGNAL (Sagmeister): Warm amber/cream, dusty rose, sage green.
Handwritten-style text. Close-up framing. Slow drifts and floats.
Soft dissolves with warm light leaks.
```

### 2. Warm Grain — Eksell
**Mood:** Organic, friendly | **Best for:** Environmental, sustainability
```
STYLE — WARM GRAIN (Eksell): Earth tones — ochre, forest green, terracotta, cream.
Organic rounded compositions. 16mm film grain. Rounded sans-serif.
Gentle wipes and soft cuts.
```

### 3. Quiet Drama — Ray
**Mood:** Humanist, contemplative | **Best for:** Profiles, biographical
```
STYLE — QUIET DRAMA (Ray): Muted warm — sepia, deep brown, soft gold.
Portrait framing. Clean serif. Strong single-source contrast.
Slow fades to black.
```

### 4. Heritage Reel — Cassandre
**Mood:** Nostalgic, vintage | **Best for:** History, retrospectives
```
STYLE — HERITAGE REEL (Cassandre): Faded gold, burgundy, navy, sepia wash.
Elegant centered serif. Vignetting and aged film grain.
Iris wipe transitions.
```

### 5. Silk Route — Abedini
**Mood:** Flowing, mysterious | **Best for:** Global affairs, cross-cultural
```
STYLE — SILK ROUTE (Abedini): Jewel tones — deep teal, burgundy, gold, lapis blue.
Layered compositions, all depths active. Elegant spaced type.
Flowing dissolves and smooth morphs.
```

### 6. Swiss Pulse — Müller-Brockmann
**Mood:** Clinical, precise | **Best for:** Data-heavy, analytical, financial
```
STYLE — SWISS PULSE (Müller-Brockmann): Black/white + electric blue #0066FF.
Grid-locked. Helvetica Bold. Animated counters. Diagonal accents.
Grid wipe transitions.
```

### 7. Geometric Bold — Tanaka
**Mood:** Minimal, elegant | **Best for:** Lifestyle, visual essays
```
STYLE — GEOMETRIC BOLD (Tanaka): Max 3 flat colors per frame.
60% negative space. Bold type as primary element.
Single focal point. Clean cuts on beat.
```

### 8. Velvet Standard — Vignelli
**Mood:** Premium, timeless | **Best for:** Luxury, investor updates, keynotes
```
STYLE — VELVET STANDARD (Vignelli): Black, white, one accent: gold #c9a84c.
Thin ALL CAPS, wide spacing. Generous negative space.
Slow elegant cross-dissolves.
```

### 9. Digital Grid — Crouwel
**Mood:** Systematic, technical | **Best for:** Infrastructure, engineering, code
```
STYLE — DIGITAL GRID (Crouwel): Monospaced type. Dark #0a0a0a with cyan #00E5FF, amber #FFB300.
Pixel grid overlays. Terminal aesthetic. Clean wipe transitions.
```

### 10. Contact Sheet — Brodovitch
**Mood:** Editorial, investigative | **Best for:** Journalism, deep dives
```
STYLE — CONTACT SHEET (Brodovitch): High contrast B&W, desaturated accents.
Photo-editorial framing. Bold sans-serif annotations. Raw grain.
Hard cuts on beat. Snap-zooms.
```

### 11. Folk Frequency — Terrazas
**Mood:** Cultural, vivid | **Best for:** Festivals, food, heritage
```
STYLE — FOLK FREQUENCY (Terrazas): Vivid folk — hot pink, cobalt blue, sun yellow, emerald.
Bold rounded type. Folk art rhythms. Rich handmade textures.
Colorful wipes on festive rhythm.
```

### 12. Earth Pulse — Ghariokwu
**Mood:** Grounded, communal | **Best for:** Community, music/culture
```
STYLE — EARTH PULSE (Ghariokwu): Warm saturated — burnt orange, deep green, rich yellow.
Bold expressive type. Wide community framing.
Rhythmic cuts on beat. Freeze-frames.
```

### 13. Dream State — Tomaszewski
**Mood:** Surreal, poetic | **Best for:** Op-eds, philosophy
```
STYLE — DREAM STATE (Tomaszewski): Muted palette + one surreal accent.
Thin elegant floating type. Soft edges, atmospheric haze.
Slow morph dissolves — NEVER hard cuts.
```

### 14. Play Mode — Ahn Sang-soo
**Mood:** Playful, irreverent | **Best for:** Entertainment, pop culture
```
STYLE — PLAY MODE (Ahn Sang-soo): Electric blue, hot pink, lime green.
Bouncy spring physics. Oversized tilted text. Score cards, XP bars.
Pop cuts, bounce effects.
```

### 15. Carnival Surge — Lins
**Mood:** Euphoric, celebratory | **Best for:** Milestones, hype
```
STYLE — CARNIVAL SURGE (Lins): Max color — hot pink #FF1493, yellow #FFE000, teal #00CED1.
Collage layering. Text MASSIVE at ANGLES. Confetti bursts.
Smash cuts, flash frames.
```

### 16. Shadow Cut — Hillmann
**Mood:** Dark, cinematic | **Best for:** Exposés, investigations
```
STYLE — SHADOW CUT (Hillmann): Deep blacks, cold greys + blood red accent.
Sharp angular text. Heavy shadow. Slow creeping push-ins.
Hard cuts to black. Film noir tension.
```

### 17. Deconstructed — Brody
**Mood:** Industrial, raw | **Best for:** Tech news, punk energy
```
STYLE — DECONSTRUCTED (Brody): Dark grey #1a1a1a, rust orange #D4501E.
Type at angles, overlapping. Gritty textures, scan-line glitch.
Smash cuts with flash frames.
```

### 18. Maximalist Type — Scher
**Mood:** Loud, kinetic | **Best for:** Big announcements, launches
```
STYLE — MAXIMALIST TYPE (Scher): Red, yellow, black, white — max contrast.
Text IS the visual. Overlapping at different scales, 50-80% of frame.
Kinetic everything. Smash cuts, flash frames.
```

### 19. Data Drift — Anadol
**Mood:** Futuristic, immersive | **Best for:** AI/tech, innovation
```
STYLE — DATA DRIFT (Anadol): Iridescent — purple #7c3aed, cyan #06b6d4, deep black.
Fluid morphing compositions. Thin futuristic type.
Liquid dissolves. Particles coalesce into numbers.
```

### 20. Red Wire — Tartakover
**Mood:** Urgent, immediate | **Best for:** Breaking news, crisis
```
STYLE — RED WIRE (Tartakover): Red, black, white, emergency yellow.
Bold condensed all-caps. Split screens, tickers, timestamps.
Snap cuts, flash frames. Zero breathing room.
```

---

## Custom Styles

These 20 are starting points. Create your own by combining:
1. **Named style + designer reference** (grounds the aesthetic)
2. **Color palette with hex codes** (specific > vague)
3. **Typography rules** (font style, weight, case, spacing)
4. **Motion rules** (how elements enter/exit, timing)
5. **Transition type** (cuts, dissolves, wipes)

Example custom style:
```
STYLE — NEON TERMINAL (custom): Black #0a0a0a background, neon green #00FF41 text,
cyan #00E5FF highlights. Monospaced type throughout. Terminal cursor blinks.
Text types on character by character. Scan-line overlay at 5% opacity.
Hard cuts only. Matrix-style code rain in transitions.
```


path: references/reviewer-prompt.md
content: # Video Producer — Prompt Reviewer

You are a senior video production reviewer. You have been given a prompt that is about to be sent to HeyGen's Video Agent API for one-shot video generation. This is a one-shot API — there is no back-and-forth. The prompt must be as good as possible on the first attempt.

Your job: review this prompt objectively and provide a professional assessment. Be specific. Be critical. Don't rubber-stamp.

## Review Criteria

### 1. Scene Structure
- Is the prompt structured as individual scenes (Scene 1, Scene 2, etc.) with Visual + VO + Duration per scene?
- Or is it a flat paragraph? Flat paragraphs produce generic videos. FAIL if flat.
- Are scene types varied? (Mix of A-roll, B-roll, Motion Graphics, Stock). Monotonous scene types = boring video.

### 2. Opening Hook
- Does the first scene grab attention in under 10 seconds?
- Does it lead with the most compelling statement or a question?
- Or does it start with context-setting ("In today's world...")? Context-setting openings lose viewers.

### 3. Visual Style
- Is there a visual style block? (Color palette, style descriptor, font preferences)
- Without one, Video Agent produces inconsistent visuals across scenes.
- Are the style choices appropriate for the audience? (Tech → minimalistic, Marketing → bold, Education → illustrated)

### 4. Media Type Direction
- Does each scene specify its media type? (Motion Graphics / Stock Media / AI Generated)
- Are the media types appropriate for the content? Use this matrix:
  - Data/Statistics → Motion Graphics (best)
  - Abstract Concepts → AI Generated (best)
  - Real Environments → Stock Media (best)
  - Brand Elements → Motion Graphics (best)
  - Human Emotions → Stock Media (best), NOT AI Generated (uncanny)
  - Technical Diagrams → Motion Graphics (best)

### 5. Pacing & Word Count
- Is the total word count within the 150 words/minute budget?
- 30s = ~75 words, 60s = ~150 words, 90s = ~225 words, 2min = ~300 words
- Are scene durations balanced? No single scene should be >30% of total duration.

### 6. Script Quality
- Is it written for the ear? (Conversational, short sentences, active voice)
- Or does it read like a written essay? ("It is important to note that..." = bad)
- Are there natural pauses/transitions between sections?

### 7. Narrator Framing
- Does the prompt frame the request as narrator-driven? ("A confident narrator explains...")
- Or does it use generic framing? ("Create a video about..." = weaker)

### 8. Asset Anchoring (if applicable)
- If assets were mentioned, are they anchored to specific scenes and moments?
- "Use the screenshot as B-roll when discussing features" >> "include the screenshot"

### 9. Negative Constraints
- Are negative constraints present only if explicitly requested by the user?
- "No text overlays" should NOT be a default. Text overlays improve videos.

### 10. Overall Production Quality
- Would a real video producer approve this prompt?
- Does it feel like a professional production brief or a casual request?
- Is there anything missing that would significantly improve the output?

### 11. Language Consistency (non-English videos only)
- If the video language is not English, is the script/narration in the correct language?
- Are technical directives (style block, motion verbs, frame check corrections) still in English?
- Is there a clean separation between content language and directive language?
- FAIL if the script is in English but the user requested a non-English video.
- FAIL if technical directives were translated out of English.

## Output Format

Respond with EXACTLY this format:

```
VERDICT: APPROVE | REVISE | REJECT

SCORE: X/10

STRENGTHS:
- [specific strength]
- [specific strength]

ISSUES:
- [CRITICAL] [specific issue + how to fix]
- [IMPORTANT] [specific issue + how to fix]
- [MINOR] [specific issue + how to fix]

REVISED PROMPT (only if VERDICT is REVISE):
[The full improved prompt, ready to send to the API]
```

Rules:
- APPROVE: Score 8+, no CRITICAL issues. Ready to generate.
- REVISE: Score 5-7, has issues but fixable. Provide the revised prompt.
- REJECT: Score <5, fundamental problems. List what needs to change.
- Always provide the REVISED PROMPT if verdict is REVISE. The agent will use your version directly.
- Be specific in issues. "Could be better" is useless. "Scene 3 uses AI Generated for a real office environment — switch to Stock Media" is useful.


path: references/troubleshooting.md
content: # Known Issues & Troubleshooting

## Known Bug: Video Agent "Talking Photo Not Found"

**Error message:** "The Talking Photo for the current narrator could not be found."

**Root Cause:** Confirmed as a Video Agent backend bug by HeyGen engineering (Jerry Yan). Affects `video_avatar` type narrators and stock avatar auto-selection.

**Workaround:**
- Prefer explicit `avatar_id` over auto-selection
- If `video_avatar` fails, retry with a `studio_avatar` or `photo_avatar`

**Status:** Fix in progress at HeyGen.

---

## Weird Pauses / Unnatural Silence in Videos

**Symptom:** Video has awkward pauses or breaks between sentences. Narrator stops speaking but video continues with dead air before next line.

**Root Cause:** When Video Agent receives a script shorter than the target duration, it treats the script as verbatim speech and inserts silence/breaks to stretch it to the exact requested duration. It won't ad-lib or expand — it just pads with dead air.

**Fix:** Add this directive to EVERY prompt:
> "This script is a concept and theme to convey — not a verbatim transcript. You have full creative freedom to expand, elaborate, add examples, and fill the duration naturally. Do not pad with silence or pauses."

This tells Video Agent it can expand the script naturally instead of treating it as a fixed speech transcript. Per Jerry Yan: "If you tell it it's not a script to be strictly followed but concept or theme or give it green light to expand the script it will do well."

**Status:** Skill-side fix (prompt directive). HeyGen is also tuning the default behavior but the explicit directive is the reliable workaround.

---

## Duration Variance (Expected Behavior)

Video Agent controls final video timing internally. Duration accuracy ranges from 79-174% of target across testing. This is NOT a bug.

**Mitigation:** Variable padding multipliers (Script):
- ≤30s target: 1.6x padding
- 31-119s target: 1.4x padding
- ≥120s target: 1.3x padding

With explicit `avatar_id`: ~97% duration accuracy average.
Without `avatar_id`: ~80% accuracy average.

---

## Frame Check: Video Agent Not Applying Framing

If the Video Agent ignores the FRAMING NOTE or BACKGROUND NOTE and produces black bars, letterboxing, or mismatched framing:

1. **Ensure the note is appended at the END of the prompt**, after all other content (script, style block, etc.). Video Agent processes instructions sequentially and late-prompt directives have the strongest effect.
2. **Check that the correction note was actually appended.** Log the final prompt text and verify the FRAMING NOTE / BACKGROUND NOTE block is present.
3. **photo_avatar does NOT need BACKGROUND NOTE.** Video Agent generates avatar + environment together for photo_avatars. Only append framing notes for orientation mismatches. Background notes are for studio_avatars with transparent/empty backgrounds only.

---

## Stock Avatar Auto-Selection Unreliable

When no `avatar_id` is provided, Video Agent uses narrator tags (`{{@narrator_l0ug91}}`) that sometimes fail to resolve during render.

**Fix:** Always use explicit `avatar_id` from discovery. The only exception is Quick Shot mode where the user explicitly wants speed over reliability.

---

## HTML URLs in files[] Rejected

Video Agent rejects `text/html` content type in the `files[]` array. Web pages (blogs, docs sites, articles) must be handled via Path A (contextualize) only.

**What works in files[]:** Direct file URLs (PDFs, images, videos) — but prefer download→upload→asset_id since CDN/WAF often blocks HeyGen's servers.

---

## Avatar Not Ready for Video Generation

**Symptom:** Video generation fails or produces errors immediately after creating a new avatar. The avatar exists in the HeyGen dashboard but videos referencing it fail.

**Root Cause:** Avatar creation is asynchronous. `heygen avatar create` (and `create_photo_avatar` / `create_prompt_avatar` MCP tools) return success immediately, but the avatar image is still being processed. If you submit a video request before processing completes, it fails.

**Detection:** Poll with `heygen avatar looks list --group-id <group_id>` (or MCP `list_avatar_looks`). The avatar is NOT ready until:
- `preview_image_url` is non-null
- `image_width` and `image_height` are non-zero

At the group level (`heygen avatar list`), an unready avatar will have no `preview_image_url` on the group object.

**Fix:** Poll every 10 seconds after creation, wait for preview URL to appear. Typical: 30-90s for photo avatars, 1-3 min for prompt avatars. Timeout at 5 min.

**The heygen-avatar skill handles this automatically.** If you bypass the skill, you must implement this polling yourself.

---

## Interactive Sessions Reliability

Interactive sessions (created without `--wait` and iterated via `heygen video-agent send`) have known issues:
- Sessions frequently stuck at `processing` status
- `reviewing` state may never be reached
- Follow-up messages fail with timing errors
- Stop command may not trigger video generation

**Recommendation:** Use one-shot mode for production. Interactive sessions documented for future use once HeyGen stabilizes the API.

---

## Error Code → Action

Stable CLI exit codes tell you what to do without parsing messages:

| Exit | Class | Action |
|------|-------|--------|
| `0` | ok | Continue |
| `1` | API / network | Retry with backoff. If persistent, check `--verbose` or contact HeyGen support. |
| `2` | usage | You passed a bad flag. Run `--help` on the command, fix the args, retry. |
| `3` | auth | Re-auth: `heygen auth login` or set `HEYGEN_API_KEY`. Verify with `heygen auth status`. |
| `4` | timeout under `--wait` | Operation still running server-side. stdout contains the partial resource (with `session_id` or `video_id`) — resume polling with `heygen video-agent get <id>` or `heygen video get <id>`. Do NOT re-submit. |

Common API-error hints (surfaced in stderr envelope `{error:{code,message,hint}}`):

- `402` / insufficient credits → tell the user their HeyGen plan is out of credits.
- `403` / forbidden → the resource is not owned by the caller (wrong `group_id`, private avatar).
- `404` / not found → ID is stale. Re-fetch via `heygen avatar list`, `heygen video-agent get`, etc.

---

## Polling Cadence

When `--wait` isn't an option (e.g., you want to return control to the user between polls), use a back-off schedule rather than a fixed interval:

| Age of job | Poll interval |
|------------|---------------|
| 0–2 min | every 10s |
| 2–5 min | every 30s |
| 5–10 min | every 60s |
| > 10 min | surface "taking longer than usual" once, keep polling at 60s, give up at 15 min |

If a job is stuck at the same status for >5 min, that's a signal to surface a status update or check the dashboard.

**Prefer `--wait`** on creation commands. It handles the polling internally and returns the final resource or exits `4` with a resumable `session_id` / `video_id` on timeout.

---

## Direct Video vs Video Agent — Which Endpoint?

Two ways to generate a video. Different pricing, different trade-offs.

| | **Direct Video** | **Video Agent** |
|---|-------------------|-----------------|
| Command / Tool | `heygen video create` / no MCP tool yet | `heygen video-agent create` / `create_video_agent` |
| Input | Full script + avatar + voice + scene JSON | Prompt + optional avatar/voice/style |
| Control | You author every scene | Video Agent plans scenes, pacing, motion |
| Pricing | ~$0.0333/sec | ~$0.10/sec |
| When to use | Deterministic multi-scene videos, tight control, bulk generation | Creative intros, messages, "make a video about X" requests |

The default in this skill is **Video Agent** — it's what `heygen-video` is built around. Drop to Direct Video only for batch or highly scripted workflows where Agent's autonomy is overhead.


path: release-please-config.json
content: {
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
  "release-type": "simple",
  "packages": {
    ".": {
      "package-name": "heygen-skills",
      "changelog-path": "CHANGELOG.md",
      "version-file": "VERSION",
      "extra-files": [
        {
          "type": "generic",
          "path": "SKILL.md"
        },
        {
          "type": "generic",
          "path": "heygen-video/SKILL.md"
        },
        {
          "type": "generic",
          "path": "heygen-avatar/SKILL.md"
        }
      ]
    }
  },
  "bump-minor-pre-major": false,
  "bump-patch-for-minor-pre-major": false,
  "include-component-in-tag": false,
  "tag-separator": "",
  "pull-request-title-pattern": "chore: release ${version}",
  "pull-request-header": "Release PR — bumps VERSION, SKILL.md frontmatter, and User-Agent strings from conventional commits since last release."
}


path: scripts/update-check.sh
content: #!/usr/bin/env bash
# heygen-skills update-check — periodic version check for all skills.
# Inspired by gstack's update-check pattern (MIT license).
#
# Output (one line, or nothing):
#   JUST_UPGRADED <old> <new>       — marker found from recent upgrade
#   UPGRADE_AVAILABLE <old> <new>   — remote VERSION differs from local
#   (nothing)                       — up to date, snoozed, disabled, or check skipped
#
# Env overrides (for testing):
#   HEYGEN_SKILL_DIR      — override auto-detected root
#   HEYGEN_SKILLS_STATE    — override ~/.heygen-skills state directory
#   HEYGEN_REMOTE_URL     — override remote VERSION URL
set -euo pipefail

SKILL_DIR="${HEYGEN_SKILL_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
STATE_DIR="${HEYGEN_SKILLS_STATE:-$HOME/.heygen-skills}"
CACHE_FILE="$STATE_DIR/last-update-check"
MARKER_FILE="$STATE_DIR/just-upgraded-from"
SNOOZE_FILE="$STATE_DIR/update-snoozed"
VERSION_FILE="$SKILL_DIR/VERSION"
REMOTE_URL="${HEYGEN_REMOTE_URL:-https://raw.githubusercontent.com/heygen-com/skills/master/VERSION}"

# ─── Force flag (busts cache + snooze) ────────────────────────
if [ "${1:-}" = "--force" ]; then
  rm -f "$CACHE_FILE"
  rm -f "$SNOOZE_FILE"
fi

# ─── Step 0: Check if updates are disabled ────────────────────
if [ -f "$STATE_DIR/update-check-disabled" ]; then
  exit 0
fi

# ─── Snooze helper ───────────────────────────────────────────
# check_snooze <remote_version>
#   Returns 0 if snoozed (stay quiet), 1 if not snoozed (should output).
#
#   Snooze file format: <version> <level> <epoch>
#   Level durations: 1=24h, 2=48h, 3+=7d
#   New version resets snooze.
check_snooze() {
  local remote_ver="$1"
  if [ ! -f "$SNOOZE_FILE" ]; then
    return 1
  fi
  local snoozed_ver snoozed_level snoozed_epoch
  snoozed_ver="$(awk '{print $1}' "$SNOOZE_FILE" 2>/dev/null || true)"
  snoozed_level="$(awk '{print $2}' "$SNOOZE_FILE" 2>/dev/null || true)"
  snoozed_epoch="$(awk '{print $3}' "$SNOOZE_FILE" 2>/dev/null || true)"

  # Validate: all three fields must be non-empty
  if [ -z "$snoozed_ver" ] || [ -z "$snoozed_level" ] || [ -z "$snoozed_epoch" ]; then
    return 1
  fi

  # Validate: level and epoch must be integers
  case "$snoozed_level" in *[!0-9]*) return 1 ;; esac
  case "$snoozed_epoch" in *[!0-9]*) return 1 ;; esac

  # New version dropped? Ignore snooze.
  if [ "$snoozed_ver" != "$remote_ver" ]; then
    return 1
  fi

  # Compute snooze duration based on level
  local duration
  case "$snoozed_level" in
    1) duration=86400 ;;   # 24 hours
    2) duration=172800 ;;  # 48 hours
    *) duration=604800 ;;  # 7 days (level 3+)
  esac

  local now
  now="$(date +%s)"
  local expires=$(( snoozed_epoch + duration ))
  if [ "$now" -lt "$expires" ]; then
    return 0  # still snoozed
  fi

  return 1  # snooze expired
}

# ─── Step 1: Read local version ──────────────────────────────
LOCAL=""
if [ -f "$VERSION_FILE" ]; then
  LOCAL="$(cat "$VERSION_FILE" 2>/dev/null | tr -d '[:space:]')"
fi
if [ -z "$LOCAL" ]; then
  exit 0  # No VERSION file → skip check
fi

# ─── Step 2: Check "just upgraded" marker ─────────────────────
if [ -f "$MARKER_FILE" ]; then
  OLD="$(cat "$MARKER_FILE" 2>/dev/null | tr -d '[:space:]')"
  rm -f "$MARKER_FILE"
  rm -f "$SNOOZE_FILE"
  if [ -n "$OLD" ]; then
    echo "JUST_UPGRADED $OLD $LOCAL"
  fi
fi

# ─── Step 3: Check cache freshness ──────────────────────────
# UP_TO_DATE: 60 min TTL (detect new releases quickly)
# UPGRADE_AVAILABLE: 720 min TTL (keep nagging less often)
if [ -f "$CACHE_FILE" ]; then
  CACHED="$(cat "$CACHE_FILE" 2>/dev/null || true)"
  case "$CACHED" in
    UP_TO_DATE*)        CACHE_TTL=60 ;;
    UPGRADE_AVAILABLE*) CACHE_TTL=720 ;;
    *)                  CACHE_TTL=0 ;;
  esac

  STALE=$(find "$CACHE_FILE" -mmin +$CACHE_TTL 2>/dev/null || true)
  if [ -z "$STALE" ] && [ "$CACHE_TTL" -gt 0 ]; then
    case "$CACHED" in
      UP_TO_DATE*)
        CACHED_VER="$(echo "$CACHED" | awk '{print $2}')"
        if [ "$CACHED_VER" = "$LOCAL" ]; then
          exit 0
        fi
        ;;
      UPGRADE_AVAILABLE*)
        CACHED_OLD="$(echo "$CACHED" | awk '{print $2}')"
        if [ "$CACHED_OLD" = "$LOCAL" ]; then
          CACHED_NEW="$(echo "$CACHED" | awk '{print $3}')"
          if check_snooze "$CACHED_NEW"; then
            exit 0
          fi
          echo "$CACHED"
          exit 0
        fi
        ;;
    esac
  fi
fi

# ─── Step 4: Fetch remote version ────────────────────────────
mkdir -p "$STATE_DIR"

REMOTE=""
REMOTE="$(curl -sf --max-time 5 "$REMOTE_URL" 2>/dev/null || true)"
REMOTE="$(echo "$REMOTE" | tr -d '[:space:]')"

# Validate: must look like a version number (reject HTML error pages)
if ! echo "$REMOTE" | grep -qE '^[0-9]+\.[0-9.]+$'; then
  echo "UP_TO_DATE $LOCAL" > "$CACHE_FILE"
  exit 0
fi

if [ "$LOCAL" = "$REMOTE" ]; then
  echo "UP_TO_DATE $LOCAL" > "$CACHE_FILE"
  exit 0
fi

# Versions differ — upgrade available
echo "UPGRADE_AVAILABLE $LOCAL $REMOTE" > "$CACHE_FILE"
if check_snooze "$REMOTE"; then
  exit 0
fi

echo "UPGRADE_AVAILABLE $LOCAL $REMOTE"


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)