Skill: dlxeva/ai-video-asset-manager (version 1.0.0)

--- name: ai-video-asset-manager description: AI视频制作资产管理体系。负责角色/场景/道具资产的创建、锁定、版本管理，镜头分镜规划，生成记录归档，一致性检查，返工记录。触发词：新角色、新场景、新镜头、拍视频、建资产、锁定资产、一致性检查、生成记录、返工记录、小弯开拍。当需要管理AI视频生成资产，或为新角色/场景建立资产卡时激活。 --- # AI Video Asset Manager 基于 ViMax 多智能体视频生成框架思路，适配 Runway/Kling/可灵/即梦/Pika/Sora/Veo 等工具。 ## 核心原则 1. **资产优先** — 角色/场景/道具未锁定不开始生成 2. **版本不覆盖** — 每次变更新建版本号 3. **检查前置** — 一致性检查是进入下一镜头的门槛 ## 命名规范 | 类型 | 前缀 | 示例 | |------|------|------| | 角色 | `CHAR_` | `CHAR_001_小弯` | | 场景 | `SCENE_` | `SCENE_001_游戏房` | | 道具 | `PROP_` | `PROP_001` | | 镜头 | `SHOT_` | `SHOT_001_01` | | 口播模板 | `TPL_` | `TPL_001` | | 参考图 | `REF_` | `REF_CHAR_001_front_v01` | | 生成记录 | `GEN_` | `GEN_001` | | 一致性检查 | `CHECK_` | `CHECK_001` | | 返工记录 | `RW_` | `RW_001` | ## 资产状态机 ``` 草稿 → 审核中 → 已锁定 → 使用中 → 已废弃 ↑ ↓ ← ← ← ← ← ← ← 返工 ← ← ``` ## 项目结构 每个项目独立仓库： ``` [项目名]/ ├── 00_总览.md ├── 01_资产库/ │ ├── 角色/ # CHAR_XXX_名字.md │ ├── 场景/ # SCENE_XXX_名字.md │ └── 道具/ # PROP_XXX_名字.md ├── 02_分镜/ │ ├── 00_分镜表_模板.md │ └── SHOT_XXX_XX.md ├── 03_参考图索引/ │ ├── CHAR_XXX/ │ ├── SCENE_XXX/ │ ├── TPL_XXX/ │ └── SHOT_XXX/ ├── 04_生成记录/ │ └── GEN_XXX_描述.md ├── 05_一致性检查/ │ └── CHECK_XXX_镜头ID.md └── 06_返工记录/ └── RW_XXX_镜头ID.md ``` ## 工作流 ### 新建角色资产 1. 用户提供：角色名 + 外观描述（至少：发型、服装、性格） 2. 创建 `01_资产库/角色/CHAR_XXX_名字.md` 3. 建立 `03_参考图索引/CHAR_XXX/` 目录 4. 用户提供或抓取参考图 URL → 下载到本地 5. 填写外观锁定项、可/禁用提示词 6. 状态：草稿 ### 锁定资产 条件：角色外观经过 ≥2 次生成验证 1. 确认外观锁定项全部勾选 2. 将 frontmatter 中 `status` 改为 `已锁定` 3. 在版本历史中新增条目 ### 新建镜头 1. 确认关联角色/场景已锁定 2. 创建 `02_分镜/SHOT_XXX_XX.md` 3. 绑定资产引用（角色ID、场景ID、道具ID） 4. 填写分镜信息（镜头号、叙事位置、景别、动作描述） 5. 状态：草稿 ### 生成记录归档 1. 用户提供：使用的工具（Runway/Kling/Veo等） 2. 创建/更新 `04_生成记录/GEN_XXX_描述.md` 3. 记录：prompt、参数、产出路径、工具 4. 状态：已完成 ### 一致性检查 按 `references/consistency-rules.md` 检查： | 检查项 | 通过标准 | |-------|---------| | 角色外观 | 与 `CHAR_XXX.md` 外观锁定项一致 | | 场景 | 与 `SCENE_XXX.md` 一致 | | 道具 | 与道具资产卡一致 | | 表情/姿态 | 在表情库/手势库范围内 | | 光线/色调 | 保持一致 | 全部通过 → 镜头卡标记 ✅ 有任一项不一致 → 进入返工流程 ### 返工记录 1. 创建 `06_返工记录/RW_XXX_镜头ID.md` 2. 记录：返工原因、不一致项、修复方案 3. 修复后重新通过一致性检查 ## 常用指令 | 用户说 | 执行 | |--------|------| | `新角色 [名字] [描述]` | 新建角色资产卡 | | `新场景 [名字] [描述]` | 新建场景资产卡 | | `锁定 [资产ID]` | 将资产状态改为已锁定 | | `新镜头 [角色ID] [场景ID]` | 新建镜头卡 | | `生成记录 [镜头ID] [工具]` | 引导填写生成参数 | | `一致性检查 [镜头ID]` | 执行一致性检查 | | `返工 [镜头ID]` | 创建返工记录 | | `下载素材 [URL]` | 下载图片到本地目录 | ## 项目初始化 新项目运行 `scripts/init-project.py`： ```bash python scripts/init-project.py [项目路径] [项目名] ``` 参考：`references/project-templates.md`

path: references/consistency-rules.md
content: # 一致性检查规则

## 角色外观一致性

每次生成视频前，必须对照 `CHAR_XXX.md` 的**外观锁定项**逐项核对：

### 必检项

| 检查项 | 标准 |
|-------|------|
| 脸型 | 与锁定项一致 |
| 发型/发色 | 与锁定项完全一致，禁止换发型 |
| 肤色 | 与锁定项一致 |
| 服装 | 与锁定款一致，禁止换服装 |
| 身高体型 | 与锁定项一致 |
| 标志性特征 | 眼镜/纹身/疤痕等与锁定项一致 |
| 道具搭配 | 耳机、手机等与绑定场景一致 |

### 通过标准

- 全部必检项与资产卡一致 → ✅ 通过
- 任何一项不一致 → ❌ 返工

---

## 场景一致性

对照 `SCENE_XXX.md` 核对：

| 检查项 | 标准 |
|-------|------|
| 场景类型 | 与锁定场景一致 |
| 构图比例 | 与设定比例一致（16:9 / 9:16 / 1:1）|
| 光线/色调 | 与参考图一致 |
| 背景道具 | 与场景锁定项一致 |

---

## 道具一致性

| 检查项 | 标准 |
|-------|------|
| 道具外观 | 与 `PROP_XXX.md` 一致 |
| 绑定角色 | 与镜头卡中声明的角色一致 |
| 使用状态 | 符合该道具在场景中的用途 |

---

## 表情/姿态一致性

| 检查项 | 标准 |
|-------|------|
| 表情 | 必须在 `CHAR_XXX` 表情库范围内 |
| 手势 | 必须在 `CHAR_XXX` 手势库范围内 |
| 禁止 | 表情/手势超出库的范围 |

---

## 提示词 Positive/Negative

### Positive Prompt 规则

必须包含：
- 角色外观关键词（短发、淡金色头发等）
- 服装关键词（白色休闲服）
- 场景关键词（游戏房、室内）
- 质量关键词（写实风格、高质量）

### Negative Prompt 规则

必须包含：
- 禁止换发型的词
- 禁止换服装的词
- 禁止不同演员的词

---

## 返工阈值

以下情况必须进入返工流程：

1. 角色外观任何一项与锁定项不符
2. 场景类型或主要道具与设定不符
3. 表情/手势超出库的范围
4. 连续 2 次生成一致性检查失败
5. 视频中出现未绑定的道具

---

## 检查执行人

每次生成视频后：
- **AI** 自动对照资产卡初步检查
- **用户** 最终确认是否通过
- 有争议时以资产卡锁定版本为准


path: references/project-templates.md
content: # 项目初始化模板

## 目录结构模板

每个新项目运行 `scripts/init-project.py` 后生成以下结构：

```
[项目名]/
├── 00_总览.md
├── 01_资产库/
│   ├── 角色/
│   ├── 场景/
│   └── 道具/
├── 02_分镜/
├── 03_参考图索引/
│   ├── CHAR_001/
│   ├── SCENE_001/
│   ├── TPL_001/
│   └── SHOT_001/
├── 04_生成记录/
├── 05_一致性检查/
└── 06_返工记录/
```

## 模板文件清单

| 模板路径 | 用途 |
|---------|------|
| `01_资产库/角色/00_角色资产卡_模板.md` | 新建角色时复制填写 |
| `01_资产库/场景/00_场景资产卡_模板.md` | 新建场景时复制填写 |
| `01_资产库/道具/00_道具资产卡_模板.md` | 新建道具时复制填写 |
| `02_分镜/00_分镜表_模板.md` | 分镜总表 |
| `02_分镜/00_镜头卡_模板.md` | 单镜头详细卡 |
| `03_参考图索引/00_参考图索引_模板.md` | 参考图索引 |
| `04_生成记录/00_生成记录_模板.md` | 生成记录归档 |
| `05_一致性检查/00_一致性检查表_模板.md` | 一致性检查表 |
| `06_返工记录/00_返工记录_模板.md` | 返工记录 |

## 模板复制规则

1. 从 `AI视频制作工作流/99_模板/` 目录复制
2. 复制后重命名为 `资产类型_ID_名字.md`
3. 立即填写 frontmatter 中的 `assetId` 和 `title`
4. 状态默认为草稿

## ID 编号规则

- 角色：`CHAR_001` 起，最大 `CHAR_999`
- 场景：`SCENE_001` 起
- 道具：`PROP_001` 起
- 镜头：`SHOT_场景ID_镜头序号`（如 `SHOT_001_01`）
- 模板：`TPL_001` 起
- 生成记录：`GEN_001` 起
- 一致性检查：`CHECK_001` 起
- 返工记录：`RW_001` 起

## 新项目最小启动包

新项目至少需要：
- 1 个角色资产卡（已锁定）
- 1 个场景资产卡（已锁定）
- 1 个参考图目录（有内容）


path: scripts/batch-download.py
content: """
批量下载图片/视频到本地目录
用法: python batch-download.py "目标目录" "URL1|文件名1" "URL2|文件名2" ...
"""
import os
import sys
import urllib.request
from pathlib import Path

def download_file(url: str, dest_path: Path, timeout: int = 30) -> bool:
    """下载单个文件"""
    try:
        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
        with urllib.request.urlopen(req, timeout=timeout) as response:
            data = response.read()
            dest_path.write_bytes(data)
            size = len(data) / (1024 * 1024)
            print(f"[OK] {dest_path.name} ({size:.1f}MB)")
            return True
    except Exception as e:
        print(f"[FAIL] {url} -> {e}")
        return False

def main():
    if len(sys.argv) < 3:
        print("用法: python batch-download.py \"目标目录\" \"URL|文件名\" ...")
        sys.exit(1)
    
    dest_dir = Path(sys.argv[1])
    dest_dir.mkdir(parents=True, exist_ok=True)
    
    results = []
    for item in sys.argv[2:]:
        if '|' in item:
            url, filename = item.split('|', 1)
        else:
            url = item
            filename = url.split('/')[-1].split('?')[0]
        
        if not filename:
            print(f"[SKIP] 无法从URL提取文件名: {url}")
            continue
        
        dest_path = dest_dir / filename
        ok = download_file(url.strip(), dest_path)
        results.append((url, ok))
    
    total = len(results)
    ok_count = sum(1 for _, ok in results if ok)
    print(f"\n完成: {ok_count}/{total} 成功")

if __name__ == "__main__":
    main()


path: scripts/init-project.py
content: """
初始化新AI视频项目目录结构
用法: python init-project.py "C:\\path\\to\\project" "项目名"
"""
import os
import sys
import shutil
from pathlib import Path

TEMPLATE_DIR = Path(__file__).parent.parent / "assets" / "templates"

SUBDIRS = [
    "01_资产库/角色",
    "01_资产库/场景",
    "01_资产库/道具",
    "02_分镜",
    "03_参考图索引/CHAR_001",
    "03_参考图索引/SCENE_001",
    "03_参考图索引/TPL_001",
    "03_参考图索引/SHOT_001",
    "04_生成记录",
    "05_一致性检查",
    "06_返工记录",
]

TEMPLATE_FILES = {
    "00_总览.md": "00_总览.md",
    "01_资产库/角色/00_角色资产卡_模板.md": "01_资产库/角色/00_角色资产卡_模板.md",
    "01_资产库/场景/00_场景资产卡_模板.md": "01_资产库/场景/00_场景资产卡_模板.md",
    "01_资产库/道具/00_道具资产卡_模板.md": "01_资产库/道具/00_道具资产卡_模板.md",
    "02_分镜/00_分镜表_模板.md": "02_分镜/00_分镜表_模板.md",
    "02_分镜/00_镜头卡_模板.md": "02_分镜/00_镜头卡_模板.md",
    "03_参考图索引/00_参考图索引_模板.md": "03_参考图索引/00_参考图索引_模板.md",
    "04_生成记录/00_生成记录_模板.md": "04_生成记录/00_生成记录_模板.md",
    "05_一致性检查/00_一致性检查表_模板.md": "05_一致性检查/00_一致性检查表_模板.md",
    "06_返工记录/00_返工记录_模板.md": "06_返工记录/00_返工记录_模板.md",
}

OVERVIEW_CONTENT = '''# {project_name} — AI视频制作工作流

> 基于 ViMax 多智能体视频生成框架

---

## 项目状态

| 维度 | 状态 |
|------|------|
| 角色资产 | 🔄 初始化中 |
| 场景资产 | 🔄 初始化中 |
| 叙事序列 | — |
| 口播模板 | — |

---

## 资产目录

{directory_tree}

---

## 核心原则

1. **资产优先** — 角色/场景/道具未锁定前不开始生成
2. **版本不覆盖** — 每次生成和返工均另存新版本
3. **检查前置** — 一致性检查是进入下一镜头的门槛

---

## 状态流转

```
草稿 → 审核中 → 已锁定 → 使用中 → 已废弃
  ↑                      ↓
  ← ← ← ← ← ← ← 返工 ← ←
```

---

## 下一步

1. 填写角色资产卡
2. 填写场景资产卡
3. 锁定资产
4. 新建第一个镜头
'''

def create_directory_tree(base_path):
    """生成目录树字符串"""
    lines = []
    for subdir in SUBDIRS:
        full_path = Path(base_path) / subdir
        full_path.mkdir(parents=True, exist_ok=True)
        depth = subdir.count('/')
        prefix = "├── " if depth > 0 else ""
        lines.append(f"{prefix}{Path(subdir).name}/")
    return '\n'.join(lines)

def init_project(project_path: str, project_name: str):
    base = Path(project_path)
    
    # 创建目录
    for subdir in SUBDIRS:
        (base / subdir).mkdir(parents=True, exist_ok=True)
    
    # 生成总览
    tree = create_directory_tree(base)
    overview = OVERVIEW_CONTENT.format(
        project_name=project_name,
        directory_tree=tree
    )
    (base / "00_总览.md").write_text(overview, encoding='utf-8')
    
    # 复制模板文件
    for src_name, dst_name in TEMPLATE_FILES.items():
        dst_path = base / dst_name
        if not dst_path.exists():
            dst_path.parent.mkdir(parents=True, exist_ok=True)
            # 创建空模板占位
            dst_path.write_text(f"# {dst_name} — 待填充\n", encoding='utf-8')
    
    print(f"[OK] 项目初始化完成: {base}")
    print(f"[OK] 项目名: {project_name}")

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("用法: python init-project.py \"项目路径\" \"项目名\"")
        sys.exit(1)
    
    init_project(sys.argv[1], sys.argv[2])


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