feat: 优化

This commit is contained in:
tiehongji
2026-07-03 14:41:28 +08:00
parent f44342711d
commit 546c3ef09c
16 changed files with 512 additions and 321 deletions
+4
View File
@@ -47,6 +47,10 @@ archives:
checksum:
name_template: checksums.txt
release:
prerelease: auto
make_latest: "{{ if .Prerelease }}false{{ else }}true{{ end }}"
snapshot:
version_template: "{{ incpatch .Version }}-snapshot"
+189
View File
@@ -0,0 +1,189 @@
# AI MediaKit CLI
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Go Version](https://img.shields.io/badge/go-%3E%3D1.22-blue.svg)](https://go.dev/)
[![npm version](https://img.shields.io/npm/v/@volcengine/mediakit-cli.svg)](https://www.npmjs.com/package/@volcengine/mediakit-cli)
[中文版](./README.md) | [English](./README.en.md)
The official Mediakit CLI — an FFmpeg-compatible command surface. The same command can run FFmpeg locally for editing operations such as trimming, concatenation, subtitling, mixing, and audio extraction, or switch to the cloud with a single flag to invoke AI capabilities that FFmpeg cannot deliver — quality enhancement, subtitle erasure, ASR, OCR, storyline analysis, and more. It already covers atomic capabilities across video, image, and audio modalities plus 5 AI Agent [Skills](./skills/), with 100+ audio/video atomic capabilities planned.
[Installation](#installation--quick-start) · [AI Agent Skills](#agent-skills) · [Authentication](#authentication) · [Command Structure](#command-structure) · [Advanced Usage](#advanced-usage) · [License](#license)
## Why choose mediakit-cli?
- **Comprehensive capability matrix**: spans video, image, and audio modalities, from low-level processing such as trimming / concatenation / subtitling to high-level understanding such as quality enhancement, subtitle erasure, ASR, OCR, and storyline analysis — a single command covers the full pipeline from preprocessing to final output.
- **FFmpeg-compatible, seamless migration**: local mode is built on `ffmpeg` / `ffprobe`, covering common capabilities such as trimming, concatenation, image overlay, subtitle overlay, speed adjustment, volume adjustment, flipping, fade in/out, mixing, audio/video composition, audio extraction, green-screen keying, and metadata probing — aligned with FFmpeg command intuition. Complex / AI capabilities such as filters, image-to-video, and concatenation transitions are handled in the cloud.
- **Cloud is faster and more powerful**: append `--cloud` to the same command to unlock capabilities FFmpeg cannot deliver — quality enhancement / generative quality restoration, subtitle erasure (standard / fine-grained), ASR, video OCR, highlight clipping (short drama / mini-game), storyline analysis, scene segmentation, green-screen / portrait keying, and other AI atomic capabilities. Cloud elastic compute provides second-level concurrency.
- **One command, two modes**: `--local` / `--cloud` can be switched per command; local mode is zero-cost and cloud provides elastic compute, complementing each other. They share the same parameters and `--schema`, so Agents / scripts can switch with zero modification.
- **Cost-effective processing**: leverages cloud elastic resource scheduling and off-peak batch processing strategies to provide highly competitive pricing for large batches of media tasks, significantly reducing overall token consumption and operational cost for AI applications.
## Features
| Domain | Capabilities | Runtime |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| 🎬 **Editing** (17) | Video trim · Audio trim · Video concat · Audio concat · Video image overlay · Video subtitle overlay · Video speed · Audio speed · Video volume adjust · Video filter · Video flip · Video audio fade in/out · Audio fade in/out · Audio mix · Video + audio · Extract audio · Image to video | Cloud **or** Local |
| 🎚️ **Audio** (2) | Voice / background separation · Audio metadata | Cloud |
| 🖼️ **Image AI** (5) | Image quality enhancement · Image erase & inpaint · Image quality assessment · Image OCR · Image background removal | Cloud |
| 🎥 **Video AI** (14) | Quality enhancement · Generative quality enhancement · Subtitle erasure (standard) · Fine-grained subtitle erasure · Speech-to-subtitles (ASR) · Video subtitle OCR · Highlight clipping - short drama · Highlight clipping - mini-game · Highlight extraction · Storyline analysis · Scene segmentation · Video green-screen keying · Video portrait keying · Video metadata | Cloud |
| 🔧 **Common** (2) | Async task query · Remote file fetch | Local / Cloud |
| 🚧 **Coming soon** | Video translation · Narration generation · Manga-to-animation (rolling out) | Cloud |
## Installation & Quick Start
### Requirements
Before you begin, make sure you have:
- Node.js `>=18` (`npm` / `npx`)
- Local mode: `ffmpeg` `5.1.x` and `ffprobe`
### Quick Start (Human Users)
#### Installation
Choose **one** of the following methods:
**Option 1 — one-click install:**
```bash
npx @volcengine/mediakit-cli install -y
```
**Option 2 — build from source:**
Requires Go `v1.22`+.
```bash
git clone https://github.com/volcengine/mediakit-cli.git
cd mediakit-cli
make build # Artifact: .mediakit/build/dev/mediakit-cli
# Install AI Agent Skills from local skills directory (required)
npx -y skills add ./skills -g -y
```
#### Configuration & Usage
```bash
# 1. Initialize configuration (interactive wizard)
mediakit-cli init
# 2. Environment self-check (cloud connectivity, local dependencies, install suggestions)
mediakit-cli doctor
# 3. Local editing (synchronous, no API Key needed): run FFmpeg locally to trim
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
# 4. Cloud AI (async): enhance a video to 1080p, then poll for the final result
mediakit-cli --cloud video enhance-video --video-url <url> --resolution 1080p
mediakit-cli shared query-task --task-id <task_id> --poll-complete
```
### Quick Start (AI Agent)
> The following steps are designed for AI Agents and support fully unattended workflows.
**Step 1 — Install**
```bash
npx @volcengine/mediakit-cli install -y
```
**Step 2 — Non-interactive initialization (`--yes` mode)**
```bash
# Get an API Key at: https://console.volcengine.com/imp/ai-mediakit/settings
mediakit-cli init \
--mode cloud-first \
--api-key <your-api-key> \
--yes
```
**Step 3 — Verify**
```bash
mediakit-cli doctor
mediakit-cli version
```
## Agent Skills
| Skill | Description |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `byted-mediakit-shared` | Common capabilities: task query — required by all other skills |
| `byted-mediakit-editing` | Editing: video trim, audio trim, video concat, audio concat, video image overlay, video subtitle overlay, video speed, audio speed, video volume adjust, video filter, video flip, video audio fade in/out, audio fade in/out, audio mix, video + audio, extract audio, image to video |
| `byted-mediakit-audio` | Audio: voice / background separation, audio metadata |
| `byted-mediakit-image` | Image AI: image quality enhancement, image erase & inpaint, image quality assessment, image OCR, image background removal |
| `byted-mediakit-video` | Video AI: quality enhancement, generative quality enhancement, subtitle erasure (standard), fine-grained subtitle erasure, speech-to-subtitles (ASR), video subtitle OCR, highlight clipping - short drama, highlight clipping - mini-game, highlight extraction, storyline analysis, scene segmentation, video green-screen keying, video portrait keying, video metadata |
## Authentication
`mediakit-cli` uses minimal authentication: just an API Key — no OAuth / STS / IAM role configuration required.
```bash
# Option A: choose a storage method during init (config / shell / export)
mediakit-cli init --api-key <your-api-key> --credential-store config --yes
# Option B: inject temporarily via environment variables
export MEDIAKIT_API_KEY=<your-api-key>
export MEDIAKIT_OUTPUT_PATH=<optional-custom-endpoint>
```
| Environment variable | Description |
| ---------------------- | -------------------------------------------------------------------------------------------------- |
| `MEDIAKIT_API_KEY` | Cloud API Key ([get it from the console](https://console.volcengine.com/imp/ai-mediakit/settings)) |
| `MEDIAKIT_OUTPUT_PATH` | Local mode output directory, defaults to `~/.mediakit/temp` |
## Command Structure
```
mediakit-cli [--cloud|--local] <domain> <tool> [flags]
```
- **Two modes, one command surface**: `--cloud` uses cloud elastic compute (asynchronously returns a `task_id`); `--local` uses local FFmpeg (synchronous, zero cost). Default is `cloud-first`, and it can be overridden per command with `--cloud` / `--local`.
- **Output**: cloud results are returned as URLs; local results land in `~/.mediakit/temp` (override with `--output-path` or `MEDIAKIT_OUTPUT_PATH`).
System commands:
| Command | Description |
| -------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `mediakit-cli init [--yes]` | Initialize configuration, interactive or non-interactive (Agent-friendly) |
| `mediakit-cli doctor` | Check cloud connectivity, local dependencies, and install suggestions |
| `mediakit-cli config` | View / modify configuration |
| `mediakit-cli version [--check]` | Show version; `--check` compares against the latest npm release |
| `mediakit-cli update [--check]` | Update the CLI and Skills via `npm install -g`; `--check` only checks without installing |
| `mediakit-cli --domains` | List all domains |
| `mediakit-cli --help-full` | List the full capability index |
| `mediakit-cli <domain> <tool> --schema` | Output the JSON Schema for the capability (Mode / Async / polling command metadata) |
| `mediakit-cli shared query-task --task-id X` | Query an async task; add `--poll-complete` to poll until terminal state |
## Advanced Usage
### Schema Introspection
Every capability command supports `--schema`, which outputs the input / output schema plus Mode and Async information for Agents to discover tool capabilities dynamically:
```bash
mediakit-cli video enhance-video --schema
mediakit-cli --local editing trim-video --schema
```
### Local Mode Output Naming
Local mode output files are named by the following priority:
1. Explicit `--output-path` with a complete file path (including extension) → used directly
2. Input filename available → `{original_filename}_{tool_name}.{ext}`; if a file with the same name already exists, a 6-digit random number is appended
3. No input filename → `{tool_name}-{timestamp}.{ext}`
## License
This project is open-sourced under the **MIT License**.
At runtime this software calls MediaKit cloud APIs. Using those APIs is subject to the following agreements:
- [Video Cloud Services Specific Terms](https://www.volcengine.com/docs/6448/79646?lang=zh)
- [Intelligent Processing Service Billing Rules](https://www.volcengine.com/docs/6448/104992?lang=zh)
- [Intelligent Processing Service SLA](https://www.volcengine.com/docs/6448/79648?lang=zh)
+141 -95
View File
@@ -1,143 +1,189 @@
# AI MediaKit CLI
[简体中文](./README.zh.md)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Go Version](https://img.shields.io/badge/go-%3E%3D1.22-blue.svg)](https://go.dev/)
[![npm version](https://img.shields.io/npm/v/@volcengine/mediakit-cli.svg)](https://www.npmjs.com/package/@volcengine/mediakit-cli)
<p align="center">
<img src="./assets/cover.en.png" alt="AI MediaKit CLI — interface rebuilt for LLMs · agent-native · cloud + local" width="880" />
</p>
[中文版](./README.md) | [English](./README.en.md)
> The agent-native command-line toolkit for audio & video. Run Volcengine's cloud AI and local editing through **one unified command** — built to be driven by AI agents (Claude Code, Trae, Cursor …) or by you in the terminal.
Mediakit 官方 CLI —— 兼容 FFmpeg 的命令面,同一条命令既能在本地跑 FFmpeg 完成裁剪 / 拼接 / 加字幕 / 混音 / 提取音频等剪辑操作也能一键切到云端调用画质增强、字幕擦除、ASR、OCR、剧情线分析等 FFmpeg 做不到的 AI 能力。目前已覆盖视频、图像、音频等多模态原子能力和 5 个 AI Agent [Skills](./skills/),未来预计提供 100+ 音视频原子能力。
`mediakit-cli` packs video enhancement, subtitle removal, and a full editing toolbox into a single tool. Heavy AI runs in the cloud; lightweight editing runs locally — switch with one flag, same command surface.
[安装](#安装与快速开始) · [AI Agent Skills](#agent-skills) · [鉴权](#鉴权) · [命令结构](#命令结构) · [进阶用法](#进阶用法) · [许可证](#许可证)
---
## 为什么选 mediakit-cli
## ✨ What it can do
- **完备的能力矩阵**:横跨视频、图像、音频三大模态,从裁剪 / 拼接 / 加字幕等底层处理到画质增强、字幕擦除、ASR、OCR、剧情线分析等上层理解一条命令覆盖预处理到成片输出的全链路。
- **兼容 FFmpeg无缝迁移**:本地模式基于 `ffmpeg` / `ffprobe`,覆盖裁剪、拼接、加图片、加字幕、调速、调音量、翻转、淡入淡出、混音、音视频合成、提取音频、绿幕抠图、元信息探测等常用能力,与 FFmpeg 命令直觉对齐;滤镜、图片转视频、拼接转场等复杂 / AI 能力交由云端处理。
- **云端更快更强**:同一条命令加 `--cloud` 就能升维到 FFmpeg 做不到的能力 —— 画质增强 / 生成式画质修复、字幕擦除(标准版 / 精细化、ASR、视频 OCR、高光智剪短剧 / 小游戏)、剧情故事线分析、场景切分、绿幕 / 人像抠图等 AI 原子能力,云端弹性算力提供秒级并发。
- **一命令双模态**`--local` / `--cloud` 可逐命令切换,本地零成本 + 云端弹性算力互补;共用同一份参数与 `--schema`Agent / 脚本零改造切换。
- **高性价比处理**:依托云端弹性资源调度与闲时批量处理策略,为大批量媒体任务提供极具竞争力的价格,显著降低 AI 应用的整体 Token 消耗与运行成本。
**40+ capabilities across 5 domains** — run `mediakit-cli --help-full` to list them all.
## 功能
| Domain | Capabilities | Runs on | Status |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------ |
| 🎬 **Editing** (17) | trim · concat · watermark · subtitle · speed · volume · filter · flip · fade · mix · mux · extract audio · image-to-video | cloud **or** local | ✅ Available |
| 🎚️ **Audio** (2) | voice / background separation · audio metadata probe | cloud | ✅ Available |
| 🖼️ **Image AI** (5) | enhance · object / text erase · quality scoring · OCR · background removal | cloud | ✅ Available |
| 🎥 **Video AI** (14) | enhancement (+ generative restore) · subtitle removal · ASR subtitles · OCR · highlight clipping (short-drama / mini-game) · storyline analysis · scene split · portrait & green-screen matting · metadata probe | cloud | ✅ Available |
| 🔧 **Shared** (2) | async task query · remote-file fetch | local / cloud | ✅ Available |
| 🚧 **Coming** | video translation · commentary generation · anime restyling | cloud | Rolling out |
| 领域 | 能力 | 运行 |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| 🎬 **剪辑** (17) | 视频裁剪 · 音频裁剪 · 视频拼接 · 音频拼接 · 视频加图片 · 视频加字幕 · 视频调速 · 音频调速 · 调整视频音量 · 视频添加滤镜 · 视频画面翻转 · 视频声音淡入淡出 · 音频声音淡入淡出 · 音频混合 · 视频加音频 · 提取音频 · 图片转视频 | 云端 **** 本地 |
| 🎚️ **音频** (2) | 人声背景音分离 · 音频元信息获取 | 云端 |
| 🖼️ **图像 AI** (5) | 图像画质增强 · 图像擦除修复 · 图像画质评估 · 图像文字识别 OCR · 图像背景移除 | 云端 |
| 🎥 **视频 AI** (14) | 画质增强 · 生成式画质增强 · 字幕擦除(标准版)· 精细化字幕擦除 · 语音转字幕ASR· 视频识别字幕(OCR· 高光智剪-短剧 · 高光智剪-小游戏 · 高光片段提取 · 剧情故事线分析 · 场景切分 · 视频绿幕抠图 · 视频人像抠图 · 视频元信息获取 | 云端 |
| 🔧 **通用** (2) | 异步任务查询 · 远程文件拉取 | 本地 / 云端 |
| 🚧 **即将上线** | 视频翻译 · 解说生成 · 漫剧转绘(陆续上线) | 云端 |
> AI capabilities run in the cloud (elastic compute, async). Editing runs **either** in the cloud **or** locally (sync, zero cost) — pick per command with `--cloud` / `--local`.
## 安装与快速开始
---
### 环境要求
## 🚀 Quick Start
开始之前,请确保具备以下条件:
- Node.js `>=18``npm` / `npx`
- 本地模式:`ffmpeg` `5.1.x``ffprobe`
### 快速开始(人类用户)
#### 安装
以下两种方式**任选其一**
**方式一 — 一键安装:**
```bash
npm install -g @volcengine/mediakit-cli
npx skills add volcengine/mediakit-cli -g -y # optional — install agent Skills (Claude Code / Trae / Cursor …)
export MEDIAKIT_API_KEY=<your-api-key> # from the AI MediaKit console
npx @volcengine/mediakit-cli install -y
```
# Cloud AI (async): enhance to 1080p, then poll for the result
**方式二 — 从源码构建:**
需要 Go `v1.22`+。
```bash
git clone https://github.com/volcengine/mediakit-cli.git
cd mediakit-cli
make build # 产物:.mediakit/build/dev/mediakit-cli
# 从本地 skills 目录安装 AI Agent Skills必需
npx -y skills add ./skills -g -y
```
#### 配置与使用
```bash
# 1. 初始化配置(交互式引导)
mediakit-cli init
# 2. 环境自检(检查云端连通性、本地依赖、安装建议)
mediakit-cli doctor
# 3. 本地剪辑(同步、无需 API Key本机运行 FFmpeg 完成裁剪
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
# 4. 云端 AI异步将视频画质增强至 1080p然后轮询获取最终结果
mediakit-cli --cloud video enhance-video --video-url <url> --resolution 1080p
mediakit-cli shared query-task --task-id <task_id> --poll-complete
# Local editing (sync, no key needed): runs on your machine
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
```
---
### 快速开始AI Agent
## 📦 Install
> 以下步骤面向 AI Agent全流程支持无人值守。
**第 1 步 — 安装**
```bash
# One-click install (CLI + AI agent Skills)
npx @volcengine/mediakit-cli install -y
# npm only (CLI, recommended, cross-platform — pulls the right build for your OS / arch)
npm install -g @volcengine/mediakit-cli
# npx (no install)
npx @volcengine/mediakit-cli version
# curl (macOS / Linux)
curl -fsSL https://raw.githubusercontent.com/volcengine/mediakit-cli/main/scripts/install.sh | bash
```
Pin a version or path: `VERSION=<version> INSTALL_DIR="$HOME/.local/bin" curl -fsSL …/install.sh | bash`
Verify: `mediakit-cli doctor` (checks cloud readiness + local tool deps + install hints).
### Update
The CLI checks the npm registry for new releases once a day (TTL 24h). When an update is available you'll see a hint in `stderr` and a `_notice.update` field in the stdout JSON.
**第 2 步 — 非交互式初始化(`--yes` 模式)**
```bash
mediakit-cli version --check # report current vs latest as JSON
mediakit-cli update --check # check only, no install
mediakit-cli update # install the latest via `npm install -g`
# API Key 获取地址https://console.volcengine.com/imp/ai-mediakit/settings
mediakit-cli init \
--mode cloud-first \
--api-key <your-api-key> \
--yes
```
Suppress the check with `MEDIAKIT_DISABLE_UPDATE_CHECK=1` or in CI (`CI` env set).
---
## 🤖 Use with AI Agents
`mediakit-cli` ships **AI agent Skills** that teach an agent how to call it — so a user can just say _"enhance this video to 1080p and trim the best 5 seconds"_ and the agent orchestrates the commands.
**第 3 步 — 验证**
```bash
# One command installs the Skills into every supported agent on your machine
npx skills add volcengine/mediakit-cli -g -y
mediakit-cli doctor
mediakit-cli version
```
This auto-detects and installs to **10+ runtimes** — Claude Code, Trae (CN & Global), Cursor, Codex, Gemini CLI, GitHub Copilot, OpenCode, OpenClaw, Antigravity, and more.
## Agent Skills
Every capability is also **MCP-compatible**`mediakit-cli <domain> <tool> --schema` emits a JSON Schema for MCP / Anthropic Tool Use / function-calling, no hand-written adapter needed.
| Skill | 说明 |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `byted-mediakit-shared` | 通用能力:查询任务,其它 skill 依赖此项 |
| `byted-mediakit-editing` | 剪辑:视频裁剪、音频裁剪、视频拼接、音频拼接、视频加图片、视频加字幕、视频调速、音频调速、调整视频音量、视频添加滤镜、视频画面翻转、视频声音淡入淡出、音频声音淡入淡出、音频混合、视频加音频、提取音频、图片转视频 |
| `byted-mediakit-audio` | 音频:人声背景音分离、音频元信息获取 |
| `byted-mediakit-image` | 图像 AI图像画质增强、图像擦除修复、图像画质评估、图像文字识别 OCR、图像背景移除 |
| `byted-mediakit-video` | 视频 AI画质增强、生成式画质增强、字幕擦除标准版、精细化字幕擦除、语音转字幕ASR、视频识别字幕OCR、高光智剪-短剧、高光智剪-小游戏、高光片段提取、剧情故事线分析、场景切分、视频绿幕抠图、视频人像抠图、视频元信息获取 |
---
## 鉴权
## 🧩 How it works
- **Two modes, one command surface.** `--cloud` runs heavy AI in Volcengine's cloud (elastic compute, async `task_id`); `--local` runs deterministic editing locally (sync, zero cloud cost). Default mode is `cloud-first`; per-command flags override it.
- **Command structure:** `mediakit-cli [--cloud|--local] <domain> <tool> [flags]` — domains are `editing` · `audio` · `image` · `video` · `shared`.
- **Outputs:** cloud results are returned as URLs; local results write to `~/.mediakit/temp` (override with `--output-path` or `MEDIAKIT_OUTPUT_PATH`).
---
## 📖 Documentation
- Volcengine AI MediaKit product docs & pricing: https://www.volcengine.com/docs/6448
- Full command reference & FAQ: see the docs site.
- [Error codes & exit code contract](./docs/error-codes.md) — stdout JSON protocol and exit-code rules.
---
## 🛠 Development
`mediakit-cli` 采用极简鉴权:只需一个 API Key无需 OAuth / STS / IAM 角色配置。
```bash
make build # local build → .mediakit/build/dev/mediakit-cli
make build-all # all platforms
make snapshot # snapshot release
# 方式 Ainit 时选择存储方式config / shell / export
mediakit-cli init --api-key <your-api-key> --credential-store config --yes
# 方式 B临时通过环境变量注入
export MEDIAKIT_API_KEY=<your-api-key>
export MEDIAKIT_OUTPUT_PATH=<optional-custom-endpoint>
```
Releases are produced via `.goreleaser.yml`; npm distribution via `package.json` + `scripts/install.js`; curl install via `scripts/install.sh`.
| 环境变量 | 说明 |
| ---------------------- | ------------------------------------------------------------------------------------- |
| `MEDIAKIT_API_KEY` | 云端 API Key[控制台获取](https://console.volcengine.com/imp/ai-mediakit/settings) |
| `MEDIAKIT_OUTPUT_PATH` | 本地模式输出目录,默认 `~/.mediakit/temp` |
<details>
<summary><b>Local Tool Admission</b> (FFmpeg policy)</summary>
## 命令结构
- `ffmpeg` / `ffprobe`: required, `5.1.x`, `LGPL v2.1 or later`, commercial use allowed
- Optional FFmpeg features: `openh264`, `libmp3lame`, `libass`, `libfreetype`, `libfontconfig`, `libfribidi`, `libharfbuzz`, `zlib`, `libpng`, `libjpeg-turbo`
- Boundary: external process execution only (no static/dynamic linking of local tools into the Go binary); FFmpeg stays in LGPL mode by default; no `non-free` components; no local intermediate artifacts retained (only final outputs + `fetch-file` downloads).
```
mediakit-cli [--cloud|--local] <domain> <tool> [flags]
```
</details>
- **两种模式,同一命令面**`--cloud` 走云端弹性算力(异步返回 `task_id``--local` 走本地 FFmpeg同步、零成本。默认为 `cloud-first`,可用 `--cloud` / `--local` 逐命令覆盖。
- **输出**:云端结果以 URL 返回;本地结果落到 `~/.mediakit/temp`(可用 `--output-path``MEDIAKIT_OUTPUT_PATH` 覆盖)。
---
系统命令:
## License
| 命令 | 说明 |
| -------------------------------------------- | ----------------------------------------------------------- |
| `mediakit-cli init [--yes]` | 初始化配置支持交互式或非交互式Agent 友好) |
| `mediakit-cli doctor` | 检查云端连通性、本地依赖与安装建议 |
| `mediakit-cli config` | 查看 / 修改配置项 |
| `mediakit-cli version [--check]` | 显示版本;`--check` 对比 npm 最新版 |
| `mediakit-cli update [--check]` | 通过 `npm install -g` 更新 CLI 和 Skills`--check` 只检查不安装 |
| `mediakit-cli --domains` | 列出所有域 |
| `mediakit-cli --help-full` | 列出全部能力索引 |
| `mediakit-cli <domain> <tool> --schema` | 输出该能力的 JSON SchemaMode / Async / 轮询命令等元信息) |
| `mediakit-cli shared query-task --task-id X` | 查询异步任务;加 `--poll-complete` 轮询至终态 |
This project is open-sourced under the [MIT License](./LICENSE).
## 进阶用法
This software calls MediaKit APIs at runtime. Use of these APIs is subject to the following terms and privacy policies:
### Schema 自省
- [Video Cloud Service Special Terms](https://www.volcengine.com/docs/6448/79646?lang=zh)
- [Intelligent Processing Service Billing Rules](https://www.volcengine.com/docs/6448/104992?lang=zh)
- [Intelligent Processing Service Level Agreement](https://www.volcengine.com/docs/6448/79648?lang=zh)
每个能力命令都支持 `--schema`,输出输入 / 输出 schema、Mode 与 Async 信息,供 Agent 动态发现工具能力:
```bash
mediakit-cli video enhance-video --schema
mediakit-cli --local editing trim-video --schema
```
### 本地模式输出命名
本地模式输出文件按以下优先级命名:
1. 显式 `--output-path` 指定完整文件路径(含扩展名)→ 直接使用
2. 有输入文件名 → `{原文件名}_{工具名}.{ext}`;同名文件已存在时追加 6 位随机数字
3. 无输入文件名 → `{工具名}-{时间戳}.{ext}`
## 许可证
本项目基于 **MIT 许可证** 开源。
该软件运行时会调用 MediaKit 云端 API使用这些 API 需要遵守如下协议:
- [视频云服务专有条款](https://www.volcengine.com/docs/6448/79646?lang=zh)
- [智能处理服务计费规则](https://www.volcengine.com/docs/6448/104992?lang=zh)
- [智能处理服务 SLA](https://www.volcengine.com/docs/6448/79648?lang=zh)
-143
View File
@@ -1,143 +0,0 @@
# AI MediaKit CLI
[English](./README.md)
<p align="center">
<img src="./assets/cover.png" alt="AI MediaKit CLI — 接口为模型重构 · Agent 原生 · 端云一体" width="880" />
</p>
> 面向 Agent 的音视频命令行工具集。用**一个统一的命令**调用火山引擎的云端 AI 能力、跑本地剪辑——既能让 AI AgentClaude Code、Trae、Cursor……自然语言调度也能你自己在终端直接用。
`mediakit-cli` 把画质增强、字幕擦除和一整套剪辑能力收进一个工具:重算力 AI 跑云端,轻量剪辑在本地跑——一个 flag 切换,命令写法不变。
---
## ✨ 能做什么
**5 大领域、40+ 能力** —— 运行 `mediakit-cli --help-full` 可列全。
| 领域 | 能力 | 运行 | 状态 |
| --- | --- | --- | --- |
| 🎬 **剪辑** (17) | 裁剪 · 拼接 · 加水印 · 加字幕 · 调速 · 调音量 · 滤镜 · 翻转 · 淡入淡出 · 混音 · 合成 · 提取音频 · 图片转视频 | 云端 **或** 本地 | ✅ 已上线 |
| 🎚️ **音频** (2) | 人声 / 背景音分离 · 音频元信息探测 | 云端 | ✅ 已上线 |
| 🖼️ **图像 AI** (5) | 画质增强 · 擦除修复 · 画质评分 · OCR · 背景移除 | 云端 | ✅ 已上线 |
| 🎥 **视频 AI** (14) | 画质增强(含生成式修复)· 字幕擦除 · ASR 字幕 · OCR · 高光智剪(短剧 / 小游戏)· 剧情线分析 · 场景切分 · 人像 & 绿幕抠图 · 元信息探测 | 云端 | ✅ 已上线 |
| 🔧 **通用** (2) | 异步任务查询 · 远程文件拉取 | 本地 / 云端 | ✅ 已上线 |
| 🚧 **即将上线** | 视频翻译 · 解说生成 · 漫剧转绘 | 云端 | 陆续上线 |
> AI 能力跑在云端(弹性算力、异步);剪辑能力**云端或本地**皆可(本地跑,同步、零成本)—— 每条命令用 `--cloud` / `--local` 选。
---
## 🚀 快速开始
```bash
npm install -g @volcengine/mediakit-cli
npx skills add volcengine/mediakit-cli -g -y # 可选 —— 装 Agent SkillClaude Code / Trae / Cursor …)
export MEDIAKIT_API_KEY=<你的 API Key> # 在 AI MediaKit 控制台获取
# 云端 AI异步增强到 1080p再轮询拿结果
mediakit-cli --cloud video enhance-video --video-url <url> --resolution 1080p
mediakit-cli shared query-task --task-id <task_id> --poll-complete
# 本地剪辑(同步、无需 Key在本机跑
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
```
---
## 📦 安装
```bash
# 一键安装CLI + AI Agent Skill
npx @volcengine/mediakit-cli install -y
# 仅装 CLI推荐跨平台——自动拉取对应平台 / 架构的构建产物)
npm install -g @volcengine/mediakit-cli
# npx免安装
npx @volcengine/mediakit-cli version
# curlmacOS / Linux
curl -fsSL https://raw.githubusercontent.com/volcengine/mediakit-cli/main/scripts/install.sh | bash
```
指定版本 / 路径:`VERSION=<version> INSTALL_DIR="$HOME/.local/bin" curl -fsSL …/install.sh | bash`
验证环境:`mediakit-cli doctor`(检查云端就绪 + 本地工具依赖 + 安装指引)。
### 更新
CLI 每天会向 npm registry 检查一次新版本TTL 24h。有更新时`stderr` 会出现提示stdout JSON 会带上 `_notice.update` 字段。
```bash
mediakit-cli version --check # 以 JSON 输出当前版本 vs 最新版本
mediakit-cli update --check # 只检查,不安装
mediakit-cli update # 通过 `npm install -g` 安装最新版
```
如需关闭自动检查,设置 `MEDIAKIT_DISABLE_UPDATE_CHECK=1`,或在 CI 中运行(`CI` 环境变量被设置时也会自动抑制)。
---
## 🤖 配合 AI Agent 使用
`mediakit-cli` 自带 **AI Agent Skill**——教 Agent 怎么调它。于是用户只需说一句*"把这个视频增强到 1080p再剪出最精彩的 5 秒"*Agent 就能自动编排命令。
```bash
# 一个命令把 Skill 装进本机所有支持的 Agent
npx skills add volcengine/mediakit-cli -g -y
```
它会自动检测并安装到 **10+ 种 runtime**——Claude Code、Trae国内 & 海外、Cursor、Codex、Gemini CLI、GitHub Copilot、OpenCode、OpenClaw、Antigravity 等。
每个能力还**MCP 兼容**——`mediakit-cli <domain> <tool> --schema` 吐出 JSON Schema直接喂 MCP / Anthropic Tool Use / function calling无需手写适配器。
---
## 🧩 工作原理
- **两种模式,同一套命令。** `--cloud` 把重算力 AI 跑在火山引擎云端(弹性算力、异步 `task_id``--local` 在本机跑确定性剪辑(同步、零云端成本)。默认 `cloud-first`,单命令 flag 可覆盖。
- **命令结构:** `mediakit-cli [--cloud|--local] <domain> <tool> [flags]`——domain 为 `editing` · `audio` · `image` · `video` · `shared`
- **输出:** 云端结果以 URL 返回;本地结果写到 `~/.mediakit/temp`(可用 `--output-path``MEDIAKIT_OUTPUT_PATH` 覆盖)。
---
## 📖 文档
- Volcengine AI MediaKit 产品文档 & 定价https://www.volcengine.com/docs/6448
- 完整命令参考 & FAQ见文档站。
- [错误码与退出码契约](./docs/error-codes.md) —— stdout JSON 协议与退出码规则。
---
## 🛠 开发
```bash
make build # 本地构建 → .mediakit/build/dev/mediakit-cli
make build-all # 全平台
make snapshot # snapshot release
```
发布走 `.goreleaser.yml`npm 分发走 `package.json` + `scripts/install.js`curl 安装走 `scripts/install.sh`
<details>
<summary><b>本地工具 Admission</b>FFmpeg 策略)</summary>
- `ffmpeg` / `ffprobe`:必需,`5.1.x``LGPL v2.1 或更高`,允许商用
- 可选 FFmpeg 能力:`openh264``libmp3lame``libass``libfreetype``libfontconfig``libfribidi``libharfbuzz``zlib``libpng``libjpeg-turbo`
- 边界:仅通过外部进程调用(不把本地工具静态 / 动态链接进 Go 二进制FFmpeg 默认保持 LGPL 模式;默认不引入 `non-free` 组件;不保留本地中间产物(仅保留最终产物 + `fetch-file` 下载)。
</details>
---
## License
本项目基于 [MIT 许可证](./LICENSE) 开源。
该软件运行时会调用 MediaKit 的 API使用这些 API 需要遵守如下协议和隐私政策:
- [视频云服务专用条款](https://www.volcengine.com/docs/6448/79646?lang=zh)
- [智能处理服务计费结算规则](https://www.volcengine.com/docs/6448/104992?lang=zh)
- [智能处理服务等级协议](https://www.volcengine.com/docs/6448/79648?lang=zh)
+2 -2
View File
@@ -85,8 +85,8 @@
```json
{
"error": {
"type": "invalid_parameter | security_violation | environment_error | execution_error",
"code": "missing_required_param | invalid_param_type | param_out_of_range | param_insufficient | unsupported_value | forbidden_operation | not_whitelisted | unsafe_characters | handler_not_implemented | local_unsupported | dependency_missing | execution_failed | download_failed | unknown",
"type": "InvalidParameter | SecurityViolation | EnvironmentError | ExecutionError",
"code": "MissingRequiredParam | InvalidParamType | ParamOutOfRange | ParamInsufficient | UnsupportedValue | ForbiddenOperation | NotWhitelisted | UnsafeCharacters | HandlerNotImplemented | LocalUnsupported | DependencyMissing | ExecutionFailed | DownloadFailed | Unknown",
"message": "<原始错误信息(不截断、不摘要)>"
}
}
+3 -1
View File
@@ -9,6 +9,7 @@ import (
"os"
"strings"
"mediakit-cli/internal/build"
cliconfig "mediakit-cli/internal/config"
)
@@ -86,8 +87,9 @@ func (c *Client) newRequest(method string, path string, query map[string]any, bo
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-surface", resolveSurface(c.Surface))
req.Header.Set("x-runtime", resolveRuntime(c.Runtime))
req.Header.Set("X-Amk-Task-Runtime", resolveRuntime(c.Runtime))
req.Header.Set("X-Amk-Task-Source", "cli")
req.Header.Set("X-Amk-Cli-Version", build.Version)
if c.APIKey != "" {
req.Header.Set("Authorization", "Bearer "+c.APIKey)
}
+20 -20
View File
@@ -3171,7 +3171,7 @@ func classifyErrorType(err error) string {
case strings.Contains(msg, "禁止") ||
strings.Contains(msg, "不在白名单") ||
strings.Contains(msg, "不安全字符"):
return "security_violation"
return "SecurityViolation"
case strings.Contains(msg, "必填参数") ||
strings.Contains(msg, "必须是") ||
strings.Contains(msg, "取值范围") ||
@@ -3179,13 +3179,13 @@ func classifyErrorType(err error) string {
strings.Contains(msg, "仅支持") ||
strings.Contains(msg, "必须大于") ||
strings.Contains(msg, "必须大于等于"):
return "invalid_parameter"
return "InvalidParameter"
case strings.Contains(msg, "本地处理器未实现") ||
strings.Contains(msg, "不支持本地执行") ||
strings.Contains(msg, "本地依赖"):
return "environment_error"
return "EnvironmentError"
default:
return "execution_error"
return "ExecutionError"
}
}
@@ -3193,37 +3193,37 @@ func classifyErrorCode(err error) string {
msg := err.Error()
switch {
case strings.Contains(msg, "禁止"):
return "forbidden_operation"
return "ForbiddenOperation"
case strings.Contains(msg, "不在白名单"):
return "not_whitelisted"
return "NotWhitelisted"
case strings.Contains(msg, "不安全字符"):
return "unsafe_characters"
return "UnsafeCharacters"
case strings.Contains(msg, "必填参数"):
return "missing_required_param"
return "MissingRequiredParam"
case strings.Contains(msg, "必须大于等于"):
return "param_out_of_range"
return "ParamOutOfRange"
case strings.Contains(msg, "必须大于"):
return "param_out_of_range"
return "ParamOutOfRange"
case strings.Contains(msg, "取值范围"):
return "param_out_of_range"
return "ParamOutOfRange"
case strings.Contains(msg, "必须是"):
return "invalid_param_type"
return "InvalidParamType"
case strings.Contains(msg, "至少需要"):
return "param_insufficient"
return "ParamInsufficient"
case strings.Contains(msg, "仅支持"):
return "unsupported_value"
return "UnsupportedValue"
case strings.Contains(msg, "本地处理器未实现"):
return "handler_not_implemented"
return "HandlerNotImplemented"
case strings.Contains(msg, "不支持本地执行"):
return "local_unsupported"
return "LocalUnsupported"
case strings.Contains(msg, "本地依赖"):
return "dependency_missing"
return "DependencyMissing"
case strings.Contains(msg, "download failed"):
return "download_failed"
return "DownloadFailed"
case strings.Contains(msg, "执行失败"):
return "execution_failed"
return "ExecutionFailed"
default:
return "unknown"
return "Unknown"
}
}
+5 -12
View File
@@ -20,15 +20,15 @@ func Execute() error {
func newRootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "mediakit-cli",
Short: "MediaKit command line interface",
Use: "mediakit-cli",
Short: "MediaKit command line interface",
Long: `MediaKit CLI provides system commands, domain navigation, and generated capability commands.
One-click install (CLI + AI agent Skills):
npx @volcengine/mediakit-cli install -y
Update:
mediakit-cli update # install latest via npm install -g
mediakit-cli update # update CLI and AI Agent Skills via npm
mediakit-cli update --check # only report status
mediakit-cli version --check # show current vs latest
@@ -36,15 +36,8 @@ AI Agent Skills:
mediakit-cli pairs with AI agent skills (Claude Code, etc.) that
teach the agent MediaKit CLI patterns, best practices, and workflows.
Install all skills:
npx skills add volcengine/mediakit-cli -g -y
Or pick specific domains:
npx skills add volcengine/mediakit-cli -s byted-mediakit-editing -y
npx skills add volcengine/mediakit-cli -s byted-mediakit-audio -y
npx skills add volcengine/mediakit-cli -s byted-mediakit-image -y
npx skills add volcengine/mediakit-cli -s byted-mediakit-video -y
npx skills add volcengine/mediakit-cli -s byted-mediakit-shared -y`,
Reinstall all skills:
npx @volcengine/mediakit-cli install --skills-only -y`,
SilenceUsage: true,
SilenceErrors: true,
DisableAutoGenTag: true,
+99 -21
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"os/exec"
"strings"
"time"
buildinfo "mediakit-cli/internal/build"
@@ -13,16 +14,26 @@ import (
"github.com/spf13/cobra"
)
var (
checkNow = func() *updatecheck.Result {
return updatecheck.CheckNow(3 * time.Second)
}
runNpmInstall = runNpmInstallLatest
runSkillsInstall = runSkillsInstallFromPackage
)
func newUpdateCmd() *cobra.Command {
var checkOnly bool
var force bool
var asJSON bool
cmd := &cobra.Command{
Use: "update",
Short: "Check and apply mediakit-cli updates from the npm registry",
Long: "Check the npm registry for the latest @volcengine/mediakit-cli release and optionally install it via npm install -g.",
Short: "Update mediakit-cli",
Long: "Update @volcengine/mediakit-cli from npm.",
Args: cobra.NoArgs,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
r := updatecheck.CheckNow(3 * time.Second)
r := checkNow()
if r == nil {
return writeUpdatePayload(cmd, map[string]any{
"current": buildinfo.Version,
@@ -40,27 +51,57 @@ func newUpdateCmd() *cobra.Command {
payload["action"] = "skipped"
return writeUpdatePayload(cmd, payload)
}
if !r.HasUpdate {
payload["action"] = "noop"
return writeUpdatePayload(cmd, payload)
}
payload["upgrade_command"] = fmt.Sprintf("npm install -g %s@latest", updatecheck.PackageName)
payload["upgrade_command"] = "mediakit-cli update"
if checkOnly {
payload["action"] = "check"
if !asJSON {
return writeUpdateCheckText(cmd, r)
}
return writeUpdatePayload(cmd, payload)
}
payload["action"] = "install"
if err := runNpmInstallLatest(cmd); err != nil {
payload["install_status"] = "failed"
payload["error"] = err.Error()
_ = writeUpdatePayload(cmd, payload)
return err
if r.HasUpdate {
payload["action"] = "install"
if !asJSON {
fmt.Fprintf(cmd.OutOrStdout(), "Updating mediakit-cli %s → %s via npm ...\n", r.Current, r.Latest)
}
if err := runNpmInstall(cmd); err != nil {
payload["install_status"] = "failed"
payload["error"] = err.Error()
if asJSON {
_ = writeUpdatePayload(cmd, payload)
}
return err
}
payload["install_status"] = "ok"
} else {
payload["action"] = "noop"
}
shouldInstallSkills := !r.HasUpdate && force
if shouldInstallSkills {
if !asJSON {
fmt.Fprintln(cmd.OutOrStdout(), "\nInstalling skills from the current npm package ...")
}
if err := runSkillsInstall(cmd); err != nil {
payload["skills_action"] = "failed"
payload["skills_error"] = err.Error()
if asJSON {
_ = writeUpdatePayload(cmd, payload)
}
return err
}
payload["skills_action"] = "installed"
}
if !asJSON {
return writeUpdateText(cmd, r, shouldInstallSkills)
}
payload["install_status"] = "ok"
return writeUpdatePayload(cmd, payload)
},
}
cmd.Flags().BoolVar(&checkOnly, "check", false, "Only check for updates; do not install")
cmd.Flags().BoolVar(&force, "force", false, "Force reinstall skills from the current npm package even when CLI is already up to date")
cmd.Flags().BoolVar(&asJSON, "json", false, "Output structured JSON")
return cmd
}
@@ -71,6 +112,30 @@ func writeUpdatePayload(cmd *cobra.Command, payload map[string]any) error {
return encoder.Encode(payload)
}
func writeUpdateCheckText(cmd *cobra.Command, r *updatecheck.Result) error {
if r.HasUpdate {
_, err := fmt.Fprintf(cmd.OutOrStdout(),
"Update available: %s → %s\n Release: https://www.npmjs.com/package/%s/v/%s\n\nRun `mediakit-cli update` to install.\n",
r.Current, r.Latest, updatecheck.PackageName, r.Latest)
return err
}
_, err := fmt.Fprintf(cmd.OutOrStdout(), "mediakit-cli %s is already up to date\n", r.Current)
return err
}
func writeUpdateText(cmd *cobra.Command, r *updatecheck.Result, skillsInstalled bool) error {
if r.HasUpdate {
fmt.Fprintf(cmd.OutOrStdout(), "\n✓ Successfully updated mediakit-cli and skills from %s to %s\n", r.Current, r.Latest)
} else {
fmt.Fprintf(cmd.OutOrStdout(), "mediakit-cli %s is already up to date\n", r.Current)
}
if skillsInstalled {
_, err := fmt.Fprintln(cmd.OutOrStdout(), "✓ Skills installed from the current npm package")
return err
}
return nil
}
func runNpmInstallLatest(cmd *cobra.Command) error {
target := fmt.Sprintf("%s@latest", updatecheck.PackageName)
c := exec.Command("npm", "install", "-g", target)
@@ -79,18 +144,31 @@ func runNpmInstallLatest(cmd *cobra.Command) error {
return c.Run()
}
func runSkillsInstallFromPackage(cmd *cobra.Command) error {
c := exec.Command("npx", "-y", updatecheck.PackageName, "install", "--skills-only", "-y")
c.Stdout = os.Stderr
c.Stderr = os.Stderr
return c.Run()
}
func normalizeVersion(version string) string {
version = strings.TrimSpace(version)
version = strings.TrimPrefix(version, "v")
return strings.TrimPrefix(version, "V")
}
// newUpdateRefreshCmd is the hidden entry the detached refresh subprocess runs.
// It fetches the latest version and writes the cache, with no output. The empty
// persistent hooks override the root's update-notice hooks so the child never
// re-spawns itself or prints a nag.
func newUpdateRefreshCmd() *cobra.Command {
return &cobra.Command{
Use: "__update-refresh",
Hidden: true,
Args: cobra.NoArgs,
DisableAutoGenTag: true,
PersistentPreRun: func(cmd *cobra.Command, args []string) {},
PersistentPostRun: func(cmd *cobra.Command, args []string) {},
Use: "__update-refresh",
Hidden: true,
Args: cobra.NoArgs,
DisableAutoGenTag: true,
PersistentPreRun: func(cmd *cobra.Command, args []string) {},
PersistentPostRun: func(cmd *cobra.Command, args []string) {},
RunE: func(cmd *cobra.Command, args []string) error {
updatecheck.RunRefresh()
return nil
+1 -1
View File
@@ -32,7 +32,7 @@ func newVersionCmd() *cobra.Command {
payload["error"] = r.Err.Error()
}
if r.HasUpdate {
payload["upgrade_command"] = fmt.Sprintf("npm install -g %s@latest", updatecheck.PackageName)
payload["upgrade_command"] = "mediakit-cli update"
}
}
encoder := json.NewEncoder(cmd.OutOrStdout())
+2 -2
View File
@@ -231,8 +231,8 @@ func (e *DependencyError) Error() string {
func (e *DependencyError) StructuredError() map[string]any {
return map[string]any{
"error": map[string]any{
"type": "environment_error",
"code": "dependency_missing",
"type": "EnvironmentError",
"code": "DependencyMissing",
"message": fmt.Sprintf("命令 %s 所需本地依赖缺失: %s", e.Command, strings.Join(e.Missing, ", ")),
"install_guide": cliconfig.InstallGuide(e.Missing),
},
+3 -3
View File
@@ -16,7 +16,7 @@ func NoticePayload() map[string]any {
return map[string]any{
"current": r.Current,
"latest": r.Latest,
"command": fmt.Sprintf("npm install -g %s@latest", PackageName),
"command": "mediakit-cli update",
"message": fmt.Sprintf("New %s release available: %s -> %s", PackageName, r.Current, r.Latest),
}
}
@@ -53,8 +53,8 @@ func PrintStderrNag(w io.Writer) {
if !isCharDevice(f) {
return
}
fmt.Fprintf(w, "\n[mediakit-cli] new version available: %s -> %s\n run: npm install -g %s@latest\n",
r.Current, r.Latest, PackageName)
fmt.Fprintf(w, "\n[mediakit-cli] new version available: %s -> %s\n run: mediakit-cli update\n",
r.Current, r.Latest)
}
func isCharDevice(f *os.File) bool {
View File
View File
+25 -21
View File
@@ -1,12 +1,13 @@
#!/usr/bin/env node
const { spawnSync } = require('node:child_process')
const fs = require('node:fs')
const path = require('node:path')
const pkg = require('../package.json')
const PACKAGE_NAME = pkg.name || '@volcengine/mediakit-cli'
const SKILL_REPO = 'volcengine/mediakit-cli'
const SKILLS_DIR = path.join(__dirname, '..', 'skills')
function parseArgs(argv) {
const opts = {
@@ -14,7 +15,6 @@ function parseArgs(argv) {
skillsOnly: false,
skills: [],
yes: false,
versionTag: pkg.version || 'latest',
}
for (let i = 0; i < argv.length; i++) {
const a = argv[i]
@@ -38,17 +38,11 @@ function parseArgs(argv) {
}
break
}
case '--version': {
const next = argv[i + 1]
if (next && !next.startsWith('-')) {
opts.versionTag = next
i++
}
break
}
case '--version':
throw new Error('--version is not supported; install the npm package version you want directly')
default:
if (a.startsWith('--version=')) {
opts.versionTag = a.slice('--version='.length)
throw new Error('--version is not supported; install the npm package version you want directly')
} else if (a.startsWith('--skills=')) {
opts.skills.push(
...a
@@ -69,10 +63,21 @@ function log(msg) {
}
function whichSync(cmd) {
const probe = process.platform === 'win32' ? 'where' : 'command'
const probeArgs = process.platform === 'win32' ? [cmd] : ['-v', cmd]
const result = spawnSync(probe, probeArgs, { stdio: 'ignore', shell: true })
return result.status === 0
const pathValue = process.env.PATH || ''
const extensions =
process.platform === 'win32'
? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';')
: ['']
for (const dir of pathValue.split(path.delimiter)) {
if (!dir) continue
for (const ext of extensions) {
const candidate = path.join(dir, `${cmd}${ext}`)
if (fs.existsSync(candidate)) {
return true
}
}
}
return false
}
function runNpmInstall(target) {
@@ -91,14 +96,13 @@ function runNpmInstall(target) {
}
function runSkillsAdd(opts) {
const args = ['-y', 'skills', 'add', SKILL_REPO]
if (opts.skills.length === 0) {
args.push('-g')
} else {
const args = ['-y', 'skills', 'add', SKILLS_DIR]
if (opts.skills.length > 0) {
for (const skill of opts.skills) {
args.push('-s', skill)
}
}
args.push('-g')
if (opts.yes) {
args.push('-y')
}
@@ -120,10 +124,10 @@ async function runInstallWizard(rawArgs) {
}
if (!opts.skillsOnly) {
runNpmInstall(`${PACKAGE_NAME}@${opts.versionTag}`)
runNpmInstall(PACKAGE_NAME)
}
if (!opts.cliOnly) {
if (opts.skillsOnly && !opts.cliOnly) {
if (!whichSync('npx')) {
throw new Error('npx is required to install skills but not found in PATH')
}
+18
View File
@@ -36,6 +36,7 @@ const RELEASE_BASE_URL =
const TMP_PREFIX = "mediakit-cli-install-";
const packageRoot = path.resolve(__dirname, "..");
const binDir = path.join(packageRoot, "bin");
const skillsDir = path.join(packageRoot, "skills");
const platformMap = {
darwin: "darwin",
@@ -198,9 +199,24 @@ function findBinary(rootDir, targetName) {
return null;
}
function installSkills() {
const result = spawnSync(
"npx",
["-y", "skills", "add", skillsDir, "-g", "-y"],
{ stdio: "inherit" }
);
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
throw new Error(`npx skills add failed with exit code ${result.status}`);
}
}
async function install(options = {}) {
if (readEnv("MEDIAKIT_CLI_SKIP_DOWNLOAD", "MEDIKIT_CLI_SKIP_DOWNLOAD") === "1") {
console.log("[mediakit-cli] skip download because MEDIAKIT_CLI_SKIP_DOWNLOAD=1");
installSkills();
return;
}
@@ -211,6 +227,7 @@ async function install(options = {}) {
const targetBinary = path.join(binDir, binaryName());
if (!options.force && fs.existsSync(targetBinary)) {
installSkills();
return;
}
@@ -246,6 +263,7 @@ async function install(options = {}) {
}
console.log(`[mediakit-cli] installed ${targetBinary}`);
installSkills();
}
if (require.main === module) {