[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71K37PBVRYY17V65J9GXY9J":3,"skill-same:01M71K37PBVRYY17V65J9GXY9J":50},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":25,"linkOnly":26,"markdownContent":27,"markdownBody":27,"frontMatter":28,"refName":29,"commitSha":30,"skillDirectory":31,"forksCount":32,"repositoryHtmlUrl":33,"repositoryHomepageUrl":6,"ownerHtmlUrl":34,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":35,"install":36,"resources":49},"01M71K37PBVRYY17V65J9GXY9J","ai-animation",null,"KeiSeiLab\u002FKeiSeiKit","KeiSeiLab","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F283315582?v=4","01M71K2EW81JRFHSGF0T844B32","KeiSei Lab","01M71K2EWXTB52KWC65E55S6M2",7,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Fai-animation\u002Fskill.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[23,24],"Animation","ai animation","2026-11-10 10:12:30",false,"\u003C!-- migrated from skills\u002Fai-animation\u002Fskill.md (lowercase legacy filename) on 2026-05-02 -->\n---\nname: ai-animation\ndescription: Use when creating AI-powered animations and videos — nano-banana keyframes → Kling\u002FLuma\u002FVeo video generation via fal.ai → web-ready output. Full pipeline from concept to scroll-driven animation or video embed. Triggers on \"AI animation\", \"animate image\", \"AI video\", \"Kling\", \"image to video\", \"анимируй\", \"сделай видео из картинки\".\narguments:\n  - name: pipeline\n    description: \"Pipeline: keyframe-to-video, image-to-video, text-to-video, video-to-web (default: keyframe-to-video)\"\n    required: false\n  - name: model\n    description: \"Model: kling, luma, veo, ltx, pixverse (default: auto-select by use case)\"\n    required: false\n  - name: style\n    description: \"Visual style or reference for generation\"\n    required: false\n---\n\n# AI Animation Pipeline\n\n> nano-banana (keyframes) → fal.ai (video gen) → FFmpeg (web-ready) → scroll\u002Fembed\n> Prices verified 2026-03-13 [E1-fal.ai API docs]\n\n## Pipeline Overview\n\n```\nConcept \u002F Prompt\n  │\n  ├─→ [1. Keyframes] nano-banana → reference images (poses, angles, scenes)\n  │\n  ├─→ [2. Animate] fal.ai → Kling \u002F Luma \u002F Veo → MP4 video\n  │\n  ├─→ [3. Process] FFmpeg → frame sequence \u002F optimized video \u002F GIF\n  │\n  └─→ [4. Integrate] scroll-animation \u002F video embed \u002F motion-design\n```\n\n---\n\n## Model Selection Matrix [E1-fal.ai docs]\n\n| Use Case | Model | Endpoint | Cost\u002Fsec | Duration | Why |\n|----------|-------|----------|----------|----------|-----|\n| **Product reveal** | Kling v3 Pro | `fal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video` | $0.112 (no audio) \u002F $0.168 (audio) | 3-15s | Best motion, multi-prompt, elements |\n| **Hero loop** | Luma Ray 2 | `fal-ai\u002Fluma-dream-machine\u002Fray-2\u002Fimage-to-video` | $0.10\u002Fsec @540p | 5s, 9s | `loop: true`, start+end keyframes |\n| **Cinematic** | Veo 3 | `fal-ai\u002Fveo3` | $0.20 (no audio) \u002F $0.40 (audio) | 4-8s | Best quality + audio, 1080p |\n| **Cinematic (fast)** | Veo 3 Fast | `fal-ai\u002Fveo3\u002Ffast\u002Fimage-to-video` | $0.10 (no audio) \u002F $0.15 (audio) | 4-8s | 50% cheaper I2V |\n| **Bulk\u002Fcheap** | LTX 2.0 | `fal-ai\u002Fltx-2\u002Ftext-to-video\u002Ffast` | $0.04 @1080p | 6-20s | Cheapest, up to 4K, extend\u002Fretake |\n| **Stylized** | PixVerse v4.5 | `fal-ai\u002Fpixverse\u002Fv4.5\u002Fimage-to-video` | $0.03-0.08\u002Fsec | 5-8s | anime\u002F3d\u002Fclay\u002Fcomic\u002Fcyberpunk + camera presets |\n\n### Quick Decision\n\n- Loop for hero section? → **Luma Ray 2** (loop: true)\n- Animate a product\u002Fdesign comp? → **Kling v3 Pro**\n- Maximum quality, budget OK? → **Veo 3**\n- Need 10+ videos cheap? → **LTX 2.0**\n- Specific art style? → **PixVerse v4.5**\n\n---\n\n## Step 1: Generate Keyframes (nano-banana)\n\nGenerate reference images that will be animated into video.\n\n### Best Practices for Animation Keyframes\n\n```bash\n# Product floating in space — good for Kling rotation\nnano-banana \"premium wireless headphones floating on dark background, studio lighting, centered composition, clean edges\" -s 2K -a 16:9 -o keyframe-product\n\n# Scene for cinematic animation — good for Veo\u002FKling\nnano-banana \"cyberpunk street at golden hour, rain puddles, neon reflections, cinematic composition\" -s 2K -a 16:9 -o keyframe-scene\n\n# Character pose — good for Kling motion\nnano-banana \"3D character mascot robot waving, isometric view, white background, Pixar style\" -s 1K -a 1:1 -o keyframe-character\n\n# Hero background — good for Luma loop\nnano-banana \"abstract flowing liquid metal, iridescent purple and gold, macro photography\" -s 2K -a 16:9 -o keyframe-hero\n\n# Transparent asset for animation\nnano-banana \"floating crystal sphere with inner glow\" -t -s 1K -o keyframe-crystal\n```\n\n### nano-banana → fal.ai Upload Workflow\n\nnano-banana outputs local PNG files. To use as input for fal.ai video models:\n\n```python\nimport fal_client\n\n# Option A: Upload to fal CDN (recommended for large files)\nimage_url = fal_client.upload_file(\"keyframe-product.png\")  # → https:\u002F\u002Ffal.media\u002Ffiles\u002F...\n\n# Option B: Encode as data URI (inline, faster for small files, no CDN hop)\nimage_data = fal_client.encode_file(\"keyframe-product.png\")\n\n# Then use in any video model\nresult = fal_client.run(\"fal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video\", arguments={\n    \"start_image_url\": image_url,  # or image_data\n    \"prompt\": \"the headphones slowly rotate\",\n    \"duration\": \"5\"\n})\n```\n\n**Optimal nano-banana settings per video model:**\n\n| Video Model | nano-banana Size | Aspect | Notes |\n|------------|-----------------|--------|-------|\n| Kling v3 Pro | `-s 2K` | `-a 16:9` or `-a 9:16` or `-a 1:1` | Match `aspect_ratio` param |\n| Luma Ray 2 | `-s 2K` | `-a 16:9` or any of 6 ratios | 540p output, 2K input still better |\n| Veo 3 | `-s 2K` | `-a 16:9` or `-a 9:16` only | **Must be 720p+ and \u003C8MB** |\n| LTX 2.0 | `-s 2K` | `-a 16:9` | Flexible, handles most inputs |\n| PixVerse v4.5 | `-s 2K` | match target | Resolution matches input |\n\n### Keyframe Prompting Rules\n\n1. **Clean edges** — AI video models struggle with busy\u002Fcluttered compositions\n2. **Centered subject** — off-center subjects may drift during animation\n3. **Consistent lighting** — dramatic lighting gives video models more to work with\n4. **Simple backgrounds** — solid\u002Fgradient backgrounds → cleaner motion\n5. **Describe potential motion** — \"floating\", \"flowing\", \"spinning\" primes the composition\n6. **16:9 for video** — match the target video aspect ratio in the keyframe\n7. **High resolution** — use `-s 2K` minimum, video models downsample better than upscale\n\n---\n\n## Step 2: Animate via fal.ai\n\n### Prerequisites\n\n```bash\npip install fal-client\nexport FAL_KEY=\"your-key\"\n```\n\n### fal_client SDK Patterns (Python)\n\n```python\nimport fal_client\n\n# SYNC — blocks until done (simplest, for single generations)\nresult = fal_client.run(\"fal-ai\u002Fveo3\", arguments={...})\nvideo_url = result[\"video\"][\"url\"]\n\n# ASYNC — non-blocking\nimport asyncio\nasync def generate():\n    result = await fal_client.run_async(\"fal-ai\u002Fveo3\", arguments={...})\n    return result[\"video\"][\"url\"]\n\n# QUEUE with progress tracking — best for long jobs\nasync def generate_with_progress():\n    handler = await fal_client.submit_async(\"fal-ai\u002Fveo3\", arguments={...})\n    logs_index = 0\n    async for event in handler.iter_events(with_logs=True):\n        if isinstance(event, fal_client.Queued):\n            print(f\"Queue position: {event.position}\")\n        elif isinstance(event, (fal_client.InProgress, fal_client.Completed)):\n            for log in event.logs[logs_index:]:\n                print(log[\"message\"])\n            logs_index = len(event.logs)\n    result = await handler.get()\n    return result[\"video\"][\"url\"]\n\n# FILE UPLOAD — local file → fal CDN URL\nurl = fal_client.upload_file(\"local-image.png\")  # returns https:\u002F\u002Ffal.media\u002Ffiles\u002F...\ndata_uri = fal_client.encode_file(\"local-image.png\")  # inline data URI, no upload\n```\n\n### REST API Pattern (curl)\n\n```bash\n# Sync (blocks until done, timeout risk for long generations)\ncurl -X POST \"https:\u002F\u002Ffal.run\u002F{endpoint}\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"prompt\": \"...\", ...}'\n\n# Queue submit (non-blocking, recommended)\nREQUEST_ID=$(curl -s -X POST \"https:\u002F\u002Fqueue.fal.run\u002F{endpoint}\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"prompt\": \"...\", ...}' | jq -r '.request_id')\n\n# Check status\ncurl -s \"https:\u002F\u002Fqueue.fal.run\u002F{endpoint}\u002Frequests\u002F$REQUEST_ID\u002Fstatus\" \\\n  -H \"Authorization: Key $FAL_KEY\"\n\n# Get result\ncurl -s \"https:\u002F\u002Fqueue.fal.run\u002F{endpoint}\u002Frequests\u002F$REQUEST_ID\" \\\n  -H \"Authorization: Key $FAL_KEY\"\n\n# Webhook (fire and forget)\ncurl -X POST \"https:\u002F\u002Fqueue.fal.run\u002F{endpoint}\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"X-Fal-Webhook-Url: https:\u002F\u002Fyour-server.com\u002Fwebhook\" \\\n  -d '{\"prompt\": \"...\"}'\n```\n\n### Kling v3 Pro — Image to Video [E1-verified]\n\nBest for: product reveals, design comp animation, character motion, multi-shot sequences.\n\n```python\nimport fal_client\n\nresult = fal_client.run(\n    \"fal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video\",\n    arguments={\n        \"prompt\": \"the headphones slowly rotate 360 degrees, studio lighting, smooth motion\",\n        \"start_image_url\": \"https:\u002F\u002F...keyframe-product.png\",\n        \"duration\": \"5\",           # \"3\" to \"15\" seconds (string)\n        \"aspect_ratio\": \"16:9\",    # 16:9, 9:16, 1:1\n        \"generate_audio\": False,   # True adds $0.056\u002Fsec\n    }\n)\nvideo_url = result[\"video\"][\"url\"]\nprint(f\"Video: {video_url}\")\n```\n\n```javascript\n\u002F\u002F Node.js\nimport { fal } from \"@fal-ai\u002Fclient\";\n\nconst result = await fal.subscribe(\"fal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video\", {\n  input: {\n    prompt: \"the headphones slowly rotate 360 degrees\",\n    start_image_url: \"https:\u002F\u002F...keyframe.png\",\n    duration: \"5\",\n    aspect_ratio: \"16:9\",\n    generate_audio: false,\n  },\n  logs: true,\n  onQueueUpdate: (update) => {\n    if (update.status === \"IN_PROGRESS\") {\n      update.logs.map((log) => log.message).forEach(console.log);\n    }\n  },\n});\n```\n\n**Parameters:**\n| Param | Values | Default | Notes |\n|-------|--------|---------|-------|\n| `prompt` | string | — | Describe MOTION, not scene. Mutually exclusive with `multi_prompt` |\n| `start_image_url` | URL | required | Source keyframe (**not** `image_url`) |\n| `end_image_url` | URL | — | End frame for interpolation |\n| `duration` | `\"3\"`-`\"15\"` | `\"5\"` | String, per-second increments |\n| `aspect_ratio` | `16:9`, `9:16`, `1:1` | `16:9` | |\n| `generate_audio` | bool | `true` | Native audio (Chinese\u002FEnglish) |\n| `negative_prompt` | string | `\"blur, distort, and low quality\"` | |\n| `cfg_scale` | float | `0.5` | Prompt adherence strength |\n| `multi_prompt` | array | — | Multi-shot: `[{\"prompt\": \"...\", \"duration\": \"5\"}, ...]` |\n| `elements` | array | — | Character\u002Fobject consistency via reference images |\n\n**Cost [E1]:**\n- No audio: $0.112\u002Fsec → 5s = $0.56, 10s = $1.12\n- With audio: $0.168\u002Fsec → 5s = $0.84, 10s = $1.68\n- With voice control: $0.196\u002Fsec\n\n**Multi-shot example:**\n```python\nresult = fal_client.run(\"fal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video\", arguments={\n    \"start_image_url\": \"https:\u002F\u002F...keyframe.png\",\n    \"multi_prompt\": [\n        {\"prompt\": \"camera orbits around the product slowly\", \"duration\": \"5\"},\n        {\"prompt\": \"zoom in to the detail panel\", \"duration\": \"5\"}\n    ],\n    \"generate_audio\": False,\n})\n```\n\n**curl:**\n```bash\ncurl -X POST \"https:\u002F\u002Ffal.run\u002Ffal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"start_image_url\": \"https:\u002F\u002F...keyframe.png\", \"prompt\": \"rotate slowly\", \"duration\": \"5\", \"generate_audio\": false}'\n```\n\n**Prompting for motion:**\n- Describe WHAT MOVES: \"the camera slowly orbits around the product\"\n- NOT the scene: ~~\"beautiful product on dark background\"~~\n- Be specific: \"rotate 90 degrees clockwise\" > \"rotate\"\n- Keep it simple: one primary motion per clip\n\n### Luma Ray 2 — Looping Hero Videos [E1-verified]\n\nBest for: hero section backgrounds, ambient loops, living textures, start→end interpolation.\n\n```python\nresult = fal_client.run(\n    \"fal-ai\u002Fluma-dream-machine\u002Fray-2\u002Fimage-to-video\",\n    arguments={\n        \"prompt\": \"gentle flowing motion, seamless loop\",\n        \"image_url\": \"https:\u002F\u002F...keyframe-hero.png\",\n        \"loop\": True,           # seamless loop!\n        \"resolution\": \"540p\",   # 540p, 720p (2x), 1080p (4x)\n        \"duration\": \"5s\",       # \"5s\" or \"9s\"\n        \"aspect_ratio\": \"16:9\",\n    }\n)\nvideo_url = result[\"video\"][\"url\"]\n```\n\n**Key features:**\n- `loop: True` → seamless loops for `\u003Cvideo loop autoplay>` hero sections\n- `end_image_url` → interpolate between start and end keyframes (морфинг!)\n\n**Start→End keyframe example:**\n```python\nresult = fal_client.run(\"fal-ai\u002Fluma-dream-machine\u002Fray-2\u002Fimage-to-video\", arguments={\n    \"prompt\": \"smooth transformation between the two states\",\n    \"image_url\": \"https:\u002F\u002F...keyframe-start.png\",\n    \"end_image_url\": \"https:\u002F\u002F...keyframe-end.png\",\n    \"duration\": \"5s\",\n    \"aspect_ratio\": \"16:9\",\n})\n```\n\n**Parameters:**\n| Param | Values | Default | Notes |\n|-------|--------|---------|-------|\n| `prompt` | string | required | Min 3, max 5000 chars |\n| `image_url` | URL | required | Start frame |\n| `end_image_url` | URL | — | End frame (interpolation) |\n| `loop` | bool | `false` | End blended with beginning |\n| `duration` | `\"5s\"`, `\"9s\"` | `\"5s\"` | 9s costs 2x |\n| `resolution` | `\"540p\"`, `\"720p\"`, `\"1080p\"` | `\"540p\"` | 720p=2x, 1080p=4x cost |\n| `aspect_ratio` | `16:9`, `9:16`, `4:3`, `3:4`, `21:9`, `9:21` | `\"16:9\"` | |\n\n**Cost [E1]:**\n| Resolution | 5s | 9s |\n|------------|----|----|\n| 540p | $0.50 | $1.00 |\n| 720p | $1.00 | $2.00 |\n| 1080p | $2.00 | $4.00 |\n\n**curl:**\n```bash\ncurl -X POST \"https:\u002F\u002Ffal.run\u002Ffal-ai\u002Fluma-dream-machine\u002Fray-2\u002Fimage-to-video\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"prompt\": \"gentle flowing motion, seamless loop\", \"image_url\": \"https:\u002F\u002F...hero.png\", \"loop\": true, \"resolution\": \"540p\", \"duration\": \"5s\"}'\n```\n\n### Veo 3 — Maximum Quality [E1-verified]\n\nBest for: cinematic hero videos, with audio. Two variants: standard and fast.\n\n```python\n# Standard — best quality\nresult = fal_client.run(\n    \"fal-ai\u002Fveo3\",\n    arguments={\n        \"prompt\": \"cinematic reveal of headphones, dramatic lighting, camera dollies in slowly\",\n        \"image_url\": \"https:\u002F\u002F...keyframe.png\",  # optional for text-to-video\n        \"duration\": \"8s\",          # \"4s\", \"6s\", \"8s\"\n        \"resolution\": \"1080p\",     # \"720p\", \"1080p\"\n        \"aspect_ratio\": \"16:9\",    # \"16:9\", \"9:16\"\n        \"generate_audio\": True,    # unique: audio generation\n    }\n)\nvideo_url = result[\"video\"][\"url\"]\n\n# Fast I2V — 50% cheaper for image-to-video\nresult = fal_client.run(\n    \"fal-ai\u002Fveo3\u002Ffast\u002Fimage-to-video\",\n    arguments={\n        \"prompt\": \"camera slowly orbits the product\",\n        \"image_url\": \"https:\u002F\u002F...keyframe.png\",\n        \"duration\": \"8s\",\n        \"generate_audio\": False,\n    }\n)\n```\n\n**Unique:** Veo 3 generates **audio** with the video. `safety_tolerance` 1-6 (1=strict, 6=permissive). `auto_fix` auto-rewrites failing prompts. `seed` for reproducibility.\n\n**Cost [E1]:**\n| Variant | No audio | With audio |\n|---------|----------|------------|\n| Standard | $0.20\u002Fsec | $0.40\u002Fsec |\n| Fast I2V | $0.10\u002Fsec | $0.15\u002Fsec |\n\n8s standard with audio = $3.20. 8s fast I2V no audio = $0.80.\n\n**Image input constraints (Veo 3):** Max 8MB, must be 720p+, formats: PNG\u002FJPEG\u002FWebP. Aspect must be 16:9 or 9:16.\n\n**curl (fast I2V):**\n```bash\ncurl -X POST \"https:\u002F\u002Ffal.run\u002Ffal-ai\u002Fveo3\u002Ffast\u002Fimage-to-video\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"prompt\": \"gentle camera movement, ambient sounds\", \"image_url\": \"https:\u002F\u002F...keyframe.png\", \"duration\": \"8s\", \"generate_audio\": true}'\n```\n\n### LTX 2.0 Fast — Budget Option [E1-verified]\n\nBest for: bulk generation, prototyping, long videos up to 20s, up to 4K.\n\n```python\n# Text-to-video\nresult = fal_client.run(\n    \"fal-ai\u002Fltx-2\u002Ftext-to-video\u002Ffast\",\n    arguments={\n        \"prompt\": \"flowing abstract particles, dark background\",\n        \"duration\": 6,            # 6, 8, 10, 12, 14, 16, 18, 20 seconds\n        \"resolution\": \"1080p\",    # \"1080p\", \"1440p\", \"2160p\"\n        \"fps\": 25,                # 25 or 50\n        \"generate_audio\": True,\n    }\n)\n\n# Image-to-video\nresult = fal_client.run(\n    \"fal-ai\u002Fltx-2\u002Fimage-to-video\u002Ffast\",\n    arguments={\n        \"prompt\": \"gentle camera movement revealing details\",\n        \"image_url\": \"https:\u002F\u002F...keyframe.png\",\n        \"duration\": 6,\n        \"resolution\": \"1080p\",\n    }\n)\n\n# Extend existing video\nresult = fal_client.run(\n    \"fal-ai\u002Fltx-2\u002Fextend-video\",\n    arguments={\n        \"video_url\": \"https:\u002F\u002F...existing.mp4\",\n        \"prompt\": \"continue the motion smoothly\",\n        \"duration\": 5,            # max 20s total\n        \"mode\": \"end\",            # \"start\" or \"end\"\n    }\n)\n```\n\n**Cost [E1]:** $0.04\u002Fsec @1080p, $0.08\u002Fsec @1440p, $0.16\u002Fsec @2160p\n6s @1080p = $0.24. **5x cheaper** than Kling (no audio).\n\n**Extra endpoints:** `extend-video` (extend existing), `retake-video` (regenerate segment), `audio-to-video` (audio→video).\n\n### PixVerse v4.5 — Stylized [E1-verified]\n\nBest for: 3D render, cyberpunk, anime, clay, comic styles. Has camera presets.\n\n```python\nresult = fal_client.run(\n    \"fal-ai\u002Fpixverse\u002Fv4.5\u002Fimage-to-video\",\n    arguments={\n        \"prompt\": \"cyberpunk city comes alive, neon signs flicker\",\n        \"image_url\": \"https:\u002F\u002F...keyframe.png\",\n        \"style\": \"cyberpunk\",     # anime, 3d_animation, clay, comic, cyberpunk\n        \"camera_movement\": \"smooth_zoom_in\",  # see list below\n        \"resolution\": \"720p\",     # 360p, 540p, 720p, 1080p\n        \"duration\": \"5\",          # \"5\" or \"8\" (8s = 2x cost, 1080p = 5s only)\n    }\n)\n```\n\n**Camera presets:** `horizontal_left`, `horizontal_right`, `vertical_up`, `vertical_down`, `zoom_in`, `zoom_out`, `crane_up`, `quickly_zoom_in`, `quickly_zoom_out`, `smooth_zoom_in`, `camera_rotation`, `robo_arm`, `super_dolly_out`, `whip_pan`, `hitchcock`, `left_follow`, `right_follow`, `pan_left`, `pan_right`, `fix_bg`\n\n**Cost [E1]:**\n| Resolution | 5s | 8s (2x) |\n|------------|----|----|\n| 360p\u002F540p | $0.15 | $0.30 |\n| 720p | $0.20 | $0.40 |\n| 1080p | $0.40 | — (5s only) |\n\n---\n\n## Step 3: Process for Web (FFmpeg)\n\n### Download Generated Video\n\n```bash\n# Download from fal.ai URL\ncurl -o generated.mp4 \"VIDEO_URL_FROM_FAL\"\n```\n\n### Route A: Frame Sequence (for scroll animations)\n\nUse when the video will be played via GSAP ScrollTrigger or canvas scroll.\n\n```bash\n# Extract frames at 30fps, 1920x1080\nmkdir -p frames\u002Fdesktop\nffmpeg -i generated.mp4 -vf \"fps=30,scale=1920:1080\" frames\u002Fdesktop\u002Fframe_%04d.png\n\n# Convert to WebP\nfor f in frames\u002Fdesktop\u002F*.png; do\n  cwebp -q 80 \"$f\" -o \"${f%.png}.webp\"\n  rm \"$f\"\ndone\n\n# Mobile version (fewer frames, smaller)\nmkdir -p frames\u002Fmobile\nffmpeg -i generated.mp4 -vf \"fps=15,scale=960:540\" frames\u002Fmobile\u002Fframe_%04d.png\nfor f in frames\u002Fmobile\u002F*.png; do\n  cwebp -q 80 \"$f\" -o \"${f%.png}.webp\"\n  rm \"$f\"\ndone\n```\n\n→ Then use `scroll-animation` skill for GSAP ScrollTrigger canvas playback.\n\n### Route B: Optimized Video (for autoplay\u002Fembed)\n\nUse for hero video backgrounds, embedded players.\n\n```bash\n# Web-optimized MP4 (H.264 for max compat)\nffmpeg -i generated.mp4 \\\n  -c:v libx264 -preset slow -crf 23 \\\n  -c:a aac -b:a 128k \\\n  -movflags +faststart \\\n  -vf \"scale=1920:1080\" \\\n  hero-video.mp4\n\n# WebM (VP9, smaller, modern browsers)\nffmpeg -i generated.mp4 \\\n  -c:v libvpx-vp9 -crf 30 -b:v 2M \\\n  -c:a libopus -b:a 128k \\\n  -vf \"scale=1920:1080\" \\\n  hero-video.webm\n\n# AV1 (smallest, newer browsers)\nffmpeg -i generated.mp4 \\\n  -c:v libaom-av1 -crf 30 -b:v 0 \\\n  -c:a libopus -b:a 128k \\\n  -vf \"scale=1920:1080\" \\\n  hero-video.av1.mp4\n```\n\n### Route C: Scrub-Optimized Video (for scroll-driven playback)\n\n```bash\n# Every frame is keyframe = instant seeking\nffmpeg -i generated.mp4 \\\n  -c:v libx264 -preset slow -crf 23 \\\n  -g 1 -an -movflags +faststart \\\n  -vf \"scale=1920:1080\" \\\n  scrub-video.mp4\n```\n\n### Route D: Looping GIF (for social\u002Femail)\n\n```bash\n# High quality GIF with palette optimization\nffmpeg -i generated.mp4 \\\n  -vf \"fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse\" \\\n  -loop 0 output.gif\n```\n\n---\n\n## Step 4: Integrate into Web\n\n### Hero Video Background\n\n```html\n\u003Csection class=\"hero\">\n  \u003Cvideo autoplay loop muted playsinline class=\"hero-video\">\n    \u003Csource src=\"hero-video.av1.mp4\" type=\"video\u002Fmp4; codecs=av01.0.05M.08\">\n    \u003Csource src=\"hero-video.webm\" type=\"video\u002Fwebm\">\n    \u003Csource src=\"hero-video.mp4\" type=\"video\u002Fmp4\">\n  \u003C\u002Fvideo>\n  \u003Cdiv class=\"hero-content\">\n    \u003Ch1>Product Name\u003C\u002Fh1>\n  \u003C\u002Fdiv>\n\u003C\u002Fsection>\n\n\u003Cstyle>\n.hero { position: relative; height: 100vh; overflow: hidden; }\n.hero-video {\n  position: absolute; inset: 0;\n  width: 100%; height: 100%;\n  object-fit: cover;\n}\n.hero-content {\n  position: relative; z-index: 1;\n  display: grid; place-items: center;\n  height: 100%;\n}\n\u003C\u002Fstyle>\n```\n\n### Scroll-Driven Frame Sequence\n\n→ Invoke `scroll-animation` skill with the frame sequence from Step 3A.\n\n### Reduced Motion Fallback\n\n```html\n\u003Cpicture>\n  \u003Csource srcset=\"keyframe-hero.avif\" type=\"image\u002Favif\">\n  \u003Csource srcset=\"keyframe-hero.webp\" type=\"image\u002Fwebp\">\n  \u003Cimg src=\"keyframe-hero.jpg\" alt=\"Hero\" class=\"hero-fallback\">\n\u003C\u002Fpicture>\n\n\u003Cstyle>\n.hero-video { display: block; }\n.hero-fallback { display: none; }\n\n@media (prefers-reduced-motion: reduce) {\n  .hero-video { display: none; }\n  .hero-fallback { display: block; }\n}\n\u003C\u002Fstyle>\n```\n\n---\n\n## Cost Calculator [E1-verified]\n\n### Per-Video Costs (no audio, cheapest resolution)\n\n| Model | 5s | 10s | With keyframe ($0.07) |\n|-------|-----|------|-----------------------|\n| Kling v3 Pro (no audio) | $0.56 | $1.12 | $0.63 \u002F $1.19 |\n| Kling v3 Pro (audio) | $0.84 | $1.68 | $0.91 \u002F $1.75 |\n| Luma Ray 2 @540p | $0.50 | — | $0.57 |\n| Luma Ray 2 @1080p | $2.00 | — | $2.07 |\n| Veo 3 Standard (no audio) | $1.00 | — | $1.07 |\n| Veo 3 Fast I2V (no audio) | $0.50 | — | $0.57 |\n| LTX 2.0 @1080p | $0.20 | $0.40 | $0.27 \u002F $0.47 |\n| PixVerse v4.5 @720p | $0.20 | — | $0.27 |\n\n### Landing Page Budget Estimates\n\n| Scenario | Videos | Model | Est. Cost |\n|----------|--------|-------|-----------|\n| 1 hero loop @540p | 1 | Luma | ~$0.57 |\n| Product reveal 10s | 1 | Kling no audio | ~$1.19 |\n| Product + hero | 2 | Kling + Luma | ~$1.20 |\n| Full cinematic page | 3-5 | Mixed | ~$2-5 |\n| Bulk content (10 clips) | 10 | LTX 2.0 | ~$2.70 |\n| Max quality (Veo 3 audio) | 3 | Veo 3 Standard | ~$10+ |\n\n### Before Running — API Cost Guard\n\n1. Check fal.ai dashboard balance\n2. Calculate exact cost: `duration × cost_per_sec + keyframe_cost`\n3. Generate ONE test clip first\n4. Review quality before batch\n5. Tell user total cost before proceeding\n\n---\n\n## Full Pipeline Examples\n\n### Example 1: Apple-Style Product Scroll\n\n```bash\n# 1. Keyframe\nnano-banana \"premium smart watch floating on dark background, studio rim lighting, centered\" -s 2K -a 16:9 -o watch-keyframe\n\n# 2. Animate (product rotation)\npython3 -c \"\nimport fal_client\nresult = fal_client.run('fal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video', arguments={\n    'prompt': 'the watch slowly rotates 360 degrees, camera orbits smoothly, dramatic lighting',\n    'start_image_url': 'file:\u002F\u002Fwatch-keyframe.png',\n    'duration': '10',\n    'aspect_ratio': '16:9',\n    'generate_audio': False,\n})\nprint(result['video']['url'])\n\"\n\n# 3. Download & extract frames\ncurl -o watch-rotation.mp4 \"VIDEO_URL\"\nmkdir -p public\u002Fframes\u002Fwatch\u002Fdesktop public\u002Fframes\u002Fwatch\u002Fmobile\nffmpeg -i watch-rotation.mp4 -vf \"fps=30,scale=1920:1080\" public\u002Fframes\u002Fwatch\u002Fdesktop\u002Fframe_%04d.png\nffmpeg -i watch-rotation.mp4 -vf \"fps=15,scale=960:540\" public\u002Fframes\u002Fwatch\u002Fmobile\u002Fframe_%04d.png\n\n# Convert to WebP\nfor dir in public\u002Fframes\u002Fwatch\u002Fdesktop public\u002Fframes\u002Fwatch\u002Fmobile; do\n  for f in \"$dir\"\u002F*.png; do cwebp -q 80 \"$f\" -o \"${f%.png}.webp\" && rm \"$f\"; done\ndone\n\n# 4. → Use scroll-animation skill for GSAP canvas playback\n```\n\n**Cost:** ~$0.07 (keyframe) + $1.12 (Kling 10s no audio) = **$1.19**\n\n### Example 2: Hero Background Loop\n\n```bash\n# 1. Keyframe\nnano-banana \"abstract flowing liquid metal, iridescent, macro photography, dark background\" -s 2K -a 16:9 -o hero-bg\n\n# 2. Animate (seamless loop)\npython3 -c \"\nimport fal_client\nresult = fal_client.run('fal-ai\u002Fluma-dream-machine\u002Fray-2\u002Fimage-to-video', arguments={\n    'prompt': 'gentle flowing motion, metallic liquid ripples, seamless loop',\n    'image_url': 'file:\u002F\u002Fhero-bg.png',\n    'loop': True,\n    'aspect_ratio': '16:9'\n})\nprint(result['video']['url'])\n\"\n\n# 3. Optimize for web autoplay\ncurl -o hero-loop-raw.mp4 \"VIDEO_URL\"\nffmpeg -i hero-loop-raw.mp4 -c:v libx264 -preset slow -crf 23 -an -movflags +faststart hero-loop.mp4\nffmpeg -i hero-loop-raw.mp4 -c:v libvpx-vp9 -crf 30 -b:v 2M -an hero-loop.webm\n```\n\n**Cost:** ~$0.07 + $0.50 = **$0.57**\n\n### Example 3: Bulk Content Videos (Budget)\n\n```bash\n# 1. Generate 5 keyframes\nfor i in 1 2 3 4 5; do\n  nano-banana \"feature illustration $i, minimal, clean\" -s 1K -a 16:9 -o \"feature-$i\"\ndone\n\n# 2. Animate all with LTX (cheapest)\npython3 \u003C\u003C 'EOF'\nimport fal_client\nprompts = [\n    \"gentle zoom in, subtle particle effects\",\n    \"slow pan right revealing details\",\n    \"elements float upward gently\",\n    \"soft glow pulses outward\",\n    \"camera slowly pulls back\"\n]\nfor i, prompt in enumerate(prompts, 1):\n    result = fal_client.run(\"fal-ai\u002Fltx-2\u002Ftext-to-video\u002Ffast\", arguments={\n        \"prompt\": prompt,\n        \"image_url\": f\"file:\u002F\u002Ffeature-{i}.png\",\n        \"duration\": 5,\n        \"aspect_ratio\": \"16:9\"\n    })\n    print(f\"Feature {i}: {result['video']['url']}\")\nEOF\n```\n\n**Cost:** 5 × ($0.07 + $0.20) = **$1.35** for 5 videos\n\n---\n\n## Prompting Guide for Video Models\n\n### Motion Prompts (DO)\n\n- \"slowly rotates 360 degrees clockwise\"\n- \"camera dollies in from medium to close-up\"\n- \"gentle floating up and down motion\"\n- \"particles drift outward from center\"\n- \"liquid flows from left to right\"\n- \"zoom in on the detail, rack focus\"\n\n### Motion Prompts (DON'T)\n\n- ~~\"beautiful product\"~~ (describes scene, not motion)\n- ~~\"4K cinematic masterpiece\"~~ (quality tags don't help)\n- ~~\"the scene transforms into a different scene\"~~ (too complex)\n- ~~\"person walks, talks, and dances\"~~ (too many actions)\n\n### Rules\n\n1. **One motion per clip** — don't combine rotate + zoom + pan\n2. **Describe the camera** — \"camera orbits\", \"dolly in\", \"static wide\"\n3. **Describe speed** — \"slowly\", \"gently\", \"dramatically fast\"\n4. **5s for simple motion**, 10s for complex reveals\n5. **Match prompt to model** — Kling handles product\u002Fobject motion best, Luma handles ambient\u002Forganic best\n\n---\n\n## Integration with Other Skills\n\n| Skill | Role | When |\n|-------|------|------|\n| `nano-banana` | Generate keyframe images | Step 1 |\n| `video-gen` | Process video → frame sequence | Step 3A |\n| `scroll-animation` | GSAP ScrollTrigger playback | Step 4 (scroll) |\n| `motion-design` | Page transitions + micro-interactions | Step 4 (ambient) |\n| `3d-scene` | Three.js alternative to AI video | When real 3D needed |\n\n---\n\n## nano-banana via fal.ai API (Alternative to CLI)\n\nIf the nano-banana CLI is not available, use the fal.ai endpoint directly:\n\n```python\nimport fal_client\n\n# Generate keyframe via fal.ai nano-banana (Gemini image gen)\nresult = fal_client.run(\"fal-ai\u002Fnano-banana\", arguments={\n    \"prompt\": \"premium smart watch on dark background, studio rim lighting, centered, clean edges\",\n    \"num_images\": 1,\n    \"aspect_ratio\": \"16:9\",   # 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9\n    \"output_format\": \"png\",   # png, jpeg, webp\n    \"safety_tolerance\": 4,    # 1 (strict) to 6 (permissive)\n})\nkeyframe_url = result[\"images\"][0][\"url\"]\n# Cost: $0.039 per image\n\n# Now chain directly into video generation (no upload needed — already a URL!)\nvideo_result = fal_client.run(\"fal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video\", arguments={\n    \"start_image_url\": keyframe_url,  # direct URL from nano-banana\n    \"prompt\": \"watch slowly rotates 360 degrees, studio lighting\",\n    \"duration\": \"5\",\n    \"generate_audio\": False,\n})\nvideo_url = video_result[\"video\"][\"url\"]\n```\n\n**Key advantage:** nano-banana output is already a fal.ai URL, so it chains directly into any video model without upload. Total cost for keyframe + 5s Kling video: $0.039 + $0.56 = **$0.60**.\n\n```bash\n# curl version\nKEYFRAME_URL=$(curl -s -X POST \"https:\u002F\u002Ffal.run\u002Ffal-ai\u002Fnano-banana\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"prompt\": \"premium watch on dark bg, studio lighting, centered\", \"aspect_ratio\": \"16:9\"}' \\\n  | jq -r '.images[0].url')\n\ncurl -X POST \"https:\u002F\u002Fqueue.fal.run\u002Ffal-ai\u002Fkling-video\u002Fv3\u002Fpro\u002Fimage-to-video\" \\\n  -H \"Authorization: Key $FAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d \"{\\\"start_image_url\\\": \\\"$KEYFRAME_URL\\\", \\\"prompt\\\": \\\"watch rotates slowly\\\", \\\"duration\\\": \\\"5\\\", \\\"generate_audio\\\": false}\"\n```\n\n---\n\n## Workflow Summary\n\n1. **Define goal** — what animation, where on page, what triggers it?\n2. **Pick model** — use selection matrix above\n3. **Cost estimate** — calculate and tell user BEFORE generating\n4. **Generate keyframe** — nano-banana with animation-friendly composition\n5. **Animate** — fal.ai with focused motion prompt\n6. **Review** — watch output, iterate prompt if needed (budget 2-3 attempts)\n7. **Process** — choose route: frame sequence \u002F video \u002F scrub \u002F GIF\n8. **Integrate** — embed with scroll-animation, video tag, or motion-design\n9. **Fallback** — static keyframe for prefers-reduced-motion\n",{},"main","32e85218a997294f68da27ff3dfd638196186ae5","skills\u002Fai-animation",8,"https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit","https:\u002F\u002Fgithub.com\u002FKeiSeiLab","2026-10-11 11:17:46",{"source":7,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add KeiSeiLab\u002FKeiSeiKit --skill ai-animation",{"tool":42,"command":43},"bunx","bunx skills add KeiSeiLab\u002FKeiSeiKit --skill ai-animation",{"tool":45,"command":46},"pnpm","pnpm dlx skills add KeiSeiLab\u002FKeiSeiKit --skill ai-animation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Fai-animation\u002Fskill.md",true,[],[51,81,105,140,167,193],{"skillNo":52,"name":53,"nameZh":6,"description":54,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":55,"categories":56,"keywords":60,"publishedAt":25},"01M71K887N78V089XR5BWT0JAV","wave-audit","3-wave parallel audit — Wave 1 discovery (4 agents), Wave 2 verification (4 agents), Wave 3 cross-optimization (1 synthesizer). Each wave runs agents in parallel. Combines security review, runtime analysis, quality check, and constructor pattern into one unified workflow with evidence grading and Go\u002FNo-Go verdict.","https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Fwave-audit\u002FSKILL.md",[57],{"categoryNo":58,"categoryName":59,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],"wave audit","audit","unified workflow","workflow","analysis","review","verification","security review","pattern","grading","go","security","parallel","evidence","runtime","quality check","discovery","Optimization","one","check",{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":25},"01M71K85100JQS4Y10EGCTWQXW","vm-provision","End-to-end VPS provisioning — select provider → plan → provision → harden → verify (ssh-check + firewall-diff hard-gate) → handoff. 6 phases, ≥6 AskUserQuestion calls, defensive-only. Stops if either verification primitive fails.","https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Fvm-provision\u002FSKILL.md",[],[88,89,90,91,92,93,94,95,96,97,79,98,99,80,67,100,101,102,103,104],"vm","vm provision","firewall","diff","provider","select","end","calls","only","either","api","hetzner","plan","defensive","verify","intent","line",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":109,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":120,"publishedAt":25},"01M71K80ZRH2H5ES83QS97BB91","visual-explainer","Generate beautiful, self-contained HTML pages that visually explain systems, code changes, plans, and data. Use when the user asks for a diagram, architecture overview, diff review, plan review, project recap, comparison table, or any visual explanation of technical concepts. Also use proactively when you are about to render a complex ASCII table (4+ rows or 3+ columns) — present it as a styled HTML page instead.","MIT","https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Fvisual-explainer\u002FSKILL.md",[112,115],{"categoryNo":113,"categoryName":114,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":116,"categoryName":117,"taxonomyType":118,"taxonomyTypeDesc":119},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[121,122,123,124,125,126,127,128,100,129,130,131,132,133,134,135,136,137,138,139],"visual","visual explainer","explainer","project","files","image","you","architecture","generate","present","concepts","table","as","view","for","ascii table","ascii","surf","use",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":147,"publishedAt":25},"01M71K7VSD5ZWN26QJEC4T0770","video-gen","Use when generating video from frame sequences — FFmpeg extraction, WebP\u002FAVIF conversion, sprite sheets, scroll-synced playback, video encoding\u002Ftranscoding. Covers the full pipeline from video source to web-ready frame sequence or optimized video.","https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Fvideo-gen\u002FSKILL.md",[146],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[148,149,150,151,152,153,154,155,156,157,126,158,159,160,161,162,163,164,165,166],"Video","gen","video gen","ready","pipeline","default","generated","synced","false","when","conversion","directory","sequences","sequence","source","full","path","webp","target",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":171,"categories":172,"keywords":176,"publishedAt":25},"01M71K7R88RM8ENVCRZHZSMM5T","test-matrix","Use when a project needs testing BEYOND unit tests — fuzzing, property-based, load, E2E, or mutation. Five-phase hub-and-spoke pipeline composes the right mix per language × critical path × CI target, scaffolds configs + corpus + fixtures, wires CI jobs, and defines the crash\u002Fregression triage workflow. Pure-click: every decision except intake is an AskUserQuestion.","https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Ftest-matrix\u002FSKILL.md",[173],{"categoryNo":174,"categoryName":175,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量",[177,178,179,180,166,181,124,182,152,183,184,185,186,187,188,189,190,139,191,192],"test","matrix","test matrix","unit","click","regression","mix","intake","testing","decision","ci","tests","e2e","mutation","load","fuzzing",{"skillNo":194,"name":195,"nameZh":6,"description":196,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":197,"categories":198,"keywords":200,"publishedAt":25},"01M71K7N3ZY9FMMH3CSE1H8K5J","test-gen","Use when generating tests for untested code — happy path, edge cases, error handling","https:\u002F\u002Fgithub.com\u002FKeiSeiLab\u002FKeiSeiKit\u002Fblob\u002Fmain\u002Fskills\u002Ftest-gen\u002FSKILL.md",[199],{"categoryNo":174,"categoryName":175,"taxonomyType":20,"taxonomyTypeDesc":21},[201,149,177,202,166,135,203,188,204,139,157,205,206,207,208,164],"test gen","error","true","edge","file","code","error handling","name"]