# @remixmate/cli

[English](./README.md) | 简体中文

> 原名 `ab-skill-cli`（bin `ab-skill`），现已更名为 **`@remixmate/cli`**（bin **`remixmate`**）。旧包已在 npm 标记弃用，请迁移到新包。

面向 Claude Code / Codex 的 AI 媒体生成技能集。

包含 13 个技能，覆盖完整的短视频生产链路：图片 / 视频 / 语音 / 数字人素材生成、网页捕获与正文抽取、脚本编排、模板绑定、Remotion 渲染、剪映（CapCut）草稿导出，以及视频解构。

## 安装

```bash
npm install -g @remixmate/cli && remixmate install
```

`npm install` 装的是 `remixmate` 这个命令；`remixmate install` 才让 agent **自己发现**
这些 skill —— 它把内置的 `skills/` 铺进检测到的每个 agent 目录。下面这些宿主用的是
同一套 `SKILL.md` 格式，所以一份 `skills/` 全都能喂：

| 宿主 | 用户级 | 项目级 | 可用环境变量改位置 |
| --- | --- | --- | --- |
| Claude Code | `~/.claude/skills` | `./.claude/skills` | `CLAUDE_CONFIG_DIR` |
| Codex | `~/.codex/skills` | — | `CODEX_HOME` |
| WorkBuddy | `~/.workbuddy/skills` | `./.workbuddy/skills` | — |
| CodeBuddy | `~/.codebuddy/skills` | `./.codebuddy/skills` | — |
| Trae / TraeWork | — | `./.trae/skills` | — |

Trae CN 与 TraeWork CN 共用 `~/.trae-cn`，且只定义了工作区位置（`.trae/skills/<name>/`，依据是它自带的 `skill-creator`），
所以只能按项目装 —— 直接跑 `remixmate install` 会提示你进项目目录加 `--project` 重跑。
装完重启 agent 生效。

```bash
remixmate install --host workbuddy  # 只装某一个宿主
remixmate install --project         # 装到 ./<配置目录>/skills（Codex 没有项目级目录）
remixmate install --dir <path>      # 指定目录，用于上表之外的宿主
remixmate uninstall                 # 按装机记录精确卸载
```

这里的安装是**受管**的，不是 `cp -R`：每个 skills 目录下会写一份
`.remixmate-install.json` 回执，记录版本与本次铺下去的 skill 名单。靠它，重跑即原地升级、
`uninstall` 只删自己装的目录、`remixmate doctor` 能在 `npm update -g` 之后提示铺出去的副本
已经落后。同名但不是本 CLI 装的 skill，不加 `--force` 绝不覆盖。

不装也能用，只是得点名（`remixmate --list`，或让 agent 去跑 `remixmate <skill> --help`）；
agent 不会主动想到它。

## 认证

推荐方式（人类用户）：浏览器设备登录，无需手动粘贴 token：

```bash
remixmate login     # 在浏览器确认授权，凭证安全保存到本机
remixmate whoami    # 查看当前身份（绝不打印 token）
remixmate logout    # 从本机移除已存储的凭证
```

`login` 使用 OAuth 2.0 设备授权流程（RFC 8628）：CLI 给出一条已预填设备码的授权链接，你在已登录 Web 的浏览器中点一下确认，CLI 随后取回凭证并保存到系统钥匙串（或 `~/.config/remixmate/credentials.json`，权限 `0600`）。

不需要交互式终端 —— 设备流不读键盘输入，agent 宿主（Claude Code / Codex）可以直接执行并把链接转述到聊天里。只有在浏览器根本不可达时才会拒绝：CI、无桌面会话的 Linux、或设置了 `REMIXMATE_NO_BROWSER_AUTH=1`；这些场景请改用 `PRIV_TOKEN`。

CI 与 agent 宿主（ab-agent / Claude Code）继续使用 `PRIV_TOKEN` 环境变量。凭证解析优先级：

```
--token 参数  >  PRIV_TOKEN 环境变量  >  本地已存凭证（remixmate login 写入）
```

设置了 `PRIV_TOKEN` 时，`login` 会跳过，且任何命令都不会自动触发设备登录流程。

凭证只在 CLI 的 Node 侧解析一次（`src/auth/ensure.ts`），再通过环境变量注入给被调起的 Python 技能 —— 技能脚本自己不读凭证库、不读钥匙串。需要让其它命令（如维护脚本）拿到同一份凭证时，用 `exec`：

```bash
remixmate exec -- python3 scripts/test-template-pipeline.py
```

每个技能在 `skill.json` 里用 `auth` 声明鉴权需求：`required`（缺 token 就发起授权）、`optional`（有就用，没有则降级继续，如 `web-record` 只保留本地文件）、`none`（纯本地，如 `web-screenshot`）。

失败时的退出码：`4` = 需要授权，`5` = 后端不可达，`2` = 用法错误。

### 非阻塞授权（agent 宿主）

阻塞式 `login` 会一直等到设备码过期（10 分钟），超过 agent 单次工具调用的时长。改用两段式：

```bash
remixmate login --start --json               # 立刻返回授权链接，不等待
remixmate login --wait --timeout 60 --json   # 有界轮询；还没授权就再调一次
```

`--start` 把设备码写入 `0600` 的 `~/.config/remixmate/pending.json`；`--wait` 兑换后清除它。用户尚未确认时 `--wait` 返回 `{"status":"pending"}` 与退出码 4，并保留 pending 状态，可以反复调用。

### 排障

```bash
remixmate doctor            # 检查 node / python3 / Playwright / 凭证 / 后端
remixmate doctor --offline  # 跳过联网探测
```

只有凭证一项有问题时，`doctor` 退出码为 `4`。

### 列出技能

`remixmate --list` 默认输出人类可读表格（技能名 + 是否需登录 + 摘要），末尾附一行当前登录状态（写到 stderr，不干扰管道）。给工具消费请用 `remixmate --list --json`。

> 安全提示：若你此前曾把 `PRIV_TOKEN` 粘贴到聊天框或写进 shell 历史，切换到 `remixmate login` 后建议轮换该 token。

## 环境

多数技能通过 `PRIV_TOKEN` 向 ab-api 鉴权。没有有效 token（以及访问 ab-api 的网络）时，模板 / 媒体生成类技能不可用——代码是开源的，但生成能力托管在 ab-api 服务上。运行前把 `.env.example` 拷为 `.env` 并 source：

```bash
cp .env.example .env
# 修改其中的值
source .env
```

Python 技能（13 个中的 9 个）需要 `python3 >= 3.10`。`web-screenshot` / `web-record` / `web-read` 需要 Playwright（首次运行自动安装 chromium）。`ffmpeg` 仅 `video-parser` 的可选本地工具（`deconstruct_video.py`）需要；`video-parser` 默认入口走 ab-render 服务端解构，无需本地 ffmpeg。

## 技能

本项目包含 13 个 AI 媒体生成技能，覆盖从素材生成、脚本编排、模板绑定、视频渲染到剪映导出的完整视频内容生产链路。

### 技能分层

```
┌─────────────────────────────────────────────────────────────┐
│ 编排层 Skills                                                │
│  gen-script           主题 → Video DSL（脚本生成）           │
│  template-registry        DSL → TemplateBinding（模板列表）      │
│  prepare-video-assets DSL + Binding → 素材补齐（Phase 1）    │
│  render-video         RenderPlan → Remotion 渲染（Phase 3）  │
│  export-jianying      素材 → 剪映草稿 ZIP                    │
├─────────────────────────────────────────────────────────────┤
│ 原子层 Skills                                                │
│  gen-image         文生图 / 图生图（Seedream 5.0）           │
│  gen-video         文生视频（Seedance 2.0）                  │
│  gen-voice         语音合成（Minimax TTS）                   │
│  gen-digital-human 数字人口播（即梦 / 飞影）                 │
├─────────────────────────────────────────────────────────────┤
│ 工具层 Skills                                                │
│  video-parser      视频解构（音频提取 / ASR / 关键帧）       │
│  web-screenshot    网页截图（png / jpg）                     │
│  web-record        网页录屏 / 滚动录屏 / 分镜视频            │
│  web-read          网页正文抽取（markdown / 纯文本 / JSON）  │
└─────────────────────────────────────────────────────────────┘
```

### 目录结构

```
├── docs/
│   └── video-production-architecture.md   # 架构文档
├── src/                        # TypeScript CLI + http/builtin handlers
├── skills/
│   ├── gen-image/              # 原子: AI 生图（http handler）
│   ├── gen-video/              # 原子: AI 生视频（http handler）
│   ├── gen-voice/              # 原子: 语音合成（http handler）
│   ├── gen-digital-human/      # 原子: 数字人口播（http handler）
│   ├── gen-script/             # 编排: 主题 → Video DSL
│   ├── template-registry/          # 编排: 模板列表（python list_templates.py）
│   ├── prepare-video-assets/   # 编排: Phase 1 素材准备（thin wrapper）
│   ├── render-video/           # 编排: Phase 3 Remotion 渲染（含 render_video.py 实现）
│   ├── export-jianying/        # 编排: 导出剪映草稿 ZIP
│   ├── video-parser/           # 工具: 视频解构与分析
│   ├── web-screenshot/         # 工具: 无头浏览器截图（record.py 也放在这里）
│   ├── web-record/             # 工具: 无头浏览器录屏（入口指向 web-screenshot/scripts/record.py）
│   └── web-read/               # 工具: 无头浏览器正文抽取（入口指向 web-screenshot/scripts/read_page.py）
└── README.md
```

### 技能说明

| 技能 | 类型 | 说明 | 运行方式 / entry |
|------|------|------|------------------|
| gen-image | 原子 | 文生图 / 图生图（Seedream 5.0 Lite / Pro） | http handler |
| gen-video | 原子 | 文生视频（Seedance 2.0 三档） | http handler |
| gen-voice | 原子 | 语音合成（Minimax TTS） | http handler |
| gen-digital-human | 原子 | 数字人口播（即梦 / 飞影） | http handler |
| gen-script | 编排 | 主题 → Video DSL JSON | python `scripts/gen_script.py` |
| template-registry | 编排 | 模板列表（绑定逻辑内嵌于 prepare-video-assets） | python `scripts/list_templates.py` |
| prepare-video-assets | 编排 | DSL + Binding → 素材补齐 → 落库 RenderPlan | python `scripts/prepare_video_assets.py`（包装 `render_video.py --resolve-only`） |
| render-video | 编排 | job_id → Remotion 渲染 → 上传 | python `scripts/render_video.py` |
| export-jianying | 编排 | 素材 URL → 剪映草稿 ZIP（支持从 RenderPlan 自动转换） | python `scripts/gen_jianying_draft.py` |
| video-parser | 工具 | 视频 → 音频 + ASR + 关键帧 + 场景分段 | python `scripts/parse_via_render.py` |
| web-screenshot | 工具 | 网页截图（png / jpg） | python `scripts/screenshot.py` |
| web-record | 工具 | 网页录屏 / 滚动录屏 / 分镜视频（webm → mp4 → VOD） | python `../web-screenshot/scripts/record.py` |
| web-read | 工具 | 网页正文抽取（markdown / 纯文本 / 结构化 JSON） | python `../web-screenshot/scripts/read_page.py` |

### 核心链路

详见 [视频内容生产架构文档](docs/video-production-architecture.md) 和 [编排流程指南](docs/orchestration-guide.md)。

**链路 A：主题 → Remotion 视频**
```
gen-script → ✅用户确认脚本 → prepare-video-assets(--template-id)
→ ✅用户确认素材 → render-video(--job-id) → MP4
```

**链路 B：主题 → 剪映草稿**
```
gen-script → ✅用户确认脚本 → prepare-video-assets(--template-id)
→ ✅用户确认素材 → export-jianying(--from-job-id) → 剪映 ZIP
```

### 测试

```bash
# 列出所有技能（名称、tool、entry 类型）
remixmate --list

# 离线注册表 smoke + 规范守卫
npm run smoke

# CLI 单元测试（argv 解析器 + skill schema）
npm run test:cli

# Python 技能会把 --help 透传给底层脚本：
remixmate gen-script --help
remixmate prepare-video-assets --help
remixmate render-video --help
remixmate export-jianying --help
remixmate video-parser --help
remixmate web-screenshot --help
remixmate web-record --help
remixmate web-read --help
remixmate template-registry --help

# http 技能（gen-image、gen-video、gen-voice、gen-digital-human）没有
# python --help；参数见各自的 SKILL.md / skill.json。

# 查看可用音色
remixmate gen-voice --list-voices

# 查看可用模板
remixmate template-registry --list-templates
```

### 开发流程

- 克隆此项目到本地
- 在 skills 目录下各技能文件夹中开发
- 每个技能包含 `SKILL.md`（技能说明）、`version.json`（元数据）和 `scripts/`（脚本）

### 快速体验

```
@skills/gen-image/SKILL.md 生成一张熊猫的图片，9:16，调用 seedream-pro，国画风 + 严格按该文档执行
@skills/gen-video/SKILL.md 生成一段熊猫在竹林奔跑的视频，9:16，长度6秒，用 seedance-mini + 严格按该文档执行
@skills/gen-voice/SKILL.md 生成一段语音，介绍熊猫的习性，大概100字左右 + 严格按该文档执行
@skills/gen-digital-human/SKILL.md 获取数字人列表 + 严格按该文档执行
@skills/template-registry/SKILL.md 获取模版列表 + 严格按该文档执行
@skills/gen-script/SKILL.md 基于模版 image-slide，创作一个关于AI学习方法的视频 + 严格按该文档执行
```

## 许可证

MIT
