{"id":"f5e9ce3d-674b-4048-be8f-9efbed5642e2","entityType":"agent","slug":"clawhub-lenzli-zenvfx-cli","name":"ZenVFX CLI","canonicalUrl":"https://www.xpersona.co/agent/clawhub-lenzli-zenvfx-cli","canonicalPath":"/agent/clawhub-lenzli-zenvfx-cli","generatedAt":"2026-10-11T07:39:56.023Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T05:15:25.733Z","emptyReason":null},"description":"Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include... Skill: ZenVFX CLI Owner: lenzli Summary: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include... Tags: latest:1.0.19 Version history: v1.0.19 | 2026-06-16T07:03:06.861Z | user No changes detected for version 1.0.19 (no file changes). v1.0.18 | 2026-06-16T06:33:44.446Z | user - No file changes detected in this rele","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s1765re8btqpj64jxcpxn3dwgd84x7f3:zenvfx-cli","sourceUrl":"https://clawhub.ai/lenzli/zenvfx-cli","homepage":"https://clawhub.ai/lenzli/skills/zenvfx-cli","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/lenzli/zenvfx-cli","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/lenzli/skills/zenvfx-cli","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T05:15:25.733Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T05:15:25.733Z","emptyReason":null},"stars":null,"forks":null,"downloads":1149,"packageName":null,"latestVersion":"1.0.19","tractionLabel":"1.1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T05:15:25.675Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T05:15:25.733Z","lastCrawledAt":"2026-10-11T05:15:25.675Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T05:15:25.675Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.19","createdAt":"2026-06-16T07:03:06.861Z","changelog":"No changes detected for version 1.0.19 (no file changes).","fileCount":3,"zipByteSize":14998},{"version":"1.0.18","createdAt":"2026-06-16T06:33:44.446Z","changelog":"- No file changes detected in this release. - Version bump to 1.0.18 without code or documentation changes. - No new features, fixes, or updates included.","fileCount":3,"zipByteSize":13542},{"version":"1.0.17","createdAt":"2026-06-16T06:25:57.683Z","changelog":"- Removed the file: skill-card.md. - Updated documentation in SKILL.md to reflect v3 CLI changes, including: - New batch processing architecture: all edit commands accept JSON arrays or comma-separated ID lists for bulk operations. - `canvas:run` now supports both synchronous (`--wait`) and asynchronous (default) execution modes. - Clear rules for using `[S]` commands: all require the `--canvas` parameter; system auto-opens canvases as needed. - Added new commands and flags (e.g., `auth:verify`, `file:id-to-path`). - Documented parameter validation errors with explicit messages and error codes. - Updated CLI command usage examples, emphasizing proper JSON formatting (no quotes around `--data` values). - skill-card.md usage or summary file is no longer included.","fileCount":3,"zipByteSize":12856},{"version":"1.0.16","createdAt":"2026-04-28T02:34:59.432Z","changelog":"No file changes detected in this version. - No updates or modifications were made; content remains unchanged from the previous release.","fileCount":3,"zipByteSize":6476},{"version":"1.0.15","createdAt":"2026-04-21T12:49:59.793Z","changelog":"No file changes detected for version 1.0.15. - No updates or modifications in this release. - Version remains functionally identical to the previous release.","fileCount":2,"zipByteSize":5343},{"version":"1.0.14","createdAt":"2026-04-21T12:04:54.448Z","changelog":"- Added project:switch command for one-step project and workspace switching, with automatic matching rules based on userId. - Workspace automatic matching no longer depends on username, only userId. - project:switch updates both defaultProject and defaultWorkspace; supports --no-workspace option. - canvas:node:edit is replaced by canvas:node:props to modify node properties. - All instructions, command tables, and workflow updated to align with new project and node property commands.","fileCount":2,"zipByteSize":5073},{"version":"1.0.13","createdAt":"2026-04-21T11:13:14.589Z","changelog":"- Added canvas:node:edit command to support editing node name and position. - Updated important rules: now canvas:node:edit also triggers auto-save after execution. - No other command or workflow changes.","fileCount":2,"zipByteSize":4832},{"version":"1.0.12","createdAt":"2026-04-21T10:18:22.258Z","changelog":"Version 1.0.12 - No file changes detected in this release. - The functionality, commands, and documentation remain unchanged from the previous version.","fileCount":2,"zipByteSize":4790}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s1765re8btqpj64jxcpxn3dwgd84x7f3:zenvfx-cli","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T07:39:56.019Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lenzli-zenvfx-cli/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T05:15:25.733Z","emptyReason":null},"readme":"Skill: ZenVFX CLI\n\nOwner: lenzli\n\nSummary: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include...\n\nTags: latest:1.0.19\n\nVersion history:\n\nv1.0.19 | 2026-06-16T07:03:06.861Z | user\n\nNo changes detected for version 1.0.19 (no file changes).\n\nv1.0.18 | 2026-06-16T06:33:44.446Z | user\n\n- No file changes detected in this release.\n- Version bump to 1.0.18 without code or documentation changes.\n- No new features, fixes, or updates included.\n\nv1.0.17 | 2026-06-16T06:25:57.683Z | user\n\n- Removed the file: skill-card.md.\n- Updated documentation in SKILL.md to reflect v3 CLI changes, including:\n  - New batch processing architecture: all edit commands accept JSON arrays or comma-separated ID lists for bulk operations.\n  - `canvas:run` now supports both synchronous (`--wait`) and asynchronous (default) execution modes.\n  - Clear rules for using `[S]` commands: all require the `--canvas` parameter; system auto-opens canvases as needed.\n  - Added new commands and flags (e.g., `auth:verify`, `file:id-to-path`).\n  - Documented parameter validation errors with explicit messages and error codes.\n  - Updated CLI command usage examples, emphasizing proper JSON formatting (no quotes around `--data` values).\n- skill-card.md usage or summary file is no longer included.\n\nv1.0.16 | 2026-04-28T02:34:59.432Z | user\n\nNo file changes detected in this version.\n\n- No updates or modifications were made; content remains unchanged from the previous release.\n\nv1.0.15 | 2026-04-21T12:49:59.793Z | user\n\nNo file changes detected for version 1.0.15.\n\n- No updates or modifications in this release.\n- Version remains functionally identical to the previous release.\n\nv1.0.14 | 2026-04-21T12:04:54.448Z | user\n\n- Added project:switch command for one-step project and workspace switching, with automatic matching rules based on userId.\n- Workspace automatic matching no longer depends on username, only userId.\n- project:switch updates both defaultProject and defaultWorkspace; supports --no-workspace option.\n- canvas:node:edit is replaced by canvas:node:props to modify node properties.\n- All instructions, command tables, and workflow updated to align with new project and node property commands.\n\nv1.0.13 | 2026-04-21T11:13:14.589Z | user\n\n- Added canvas:node:edit command to support editing node name and position.\n- Updated important rules: now canvas:node:edit also triggers auto-save after execution.\n- No other command or workflow changes.\n\nv1.0.12 | 2026-04-21T10:18:22.258Z | user\n\nVersion 1.0.12\n\n- No file changes detected in this release.\n- The functionality, commands, and documentation remain unchanged from the previous version.\n\nv1.0.11 | 2026-04-21T08:50:16.818Z | user\n\n- Added detailed documentation for the file upload command: `file:upload --local-file <本地路径> --file-path <ZenFS路径> --project-id <id>`, including parameter descriptions and usage.\n- Expanded the node type table in the \"节点参数\" section, listing more node types and their application scenarios.\n- No changes to code or installation instructions; documentation improvement only.\n\nv1.0.10 | 2026-04-21T08:36:19.609Z | user\n\nNo file changes detected. No user-facing changes in this version.\n\nv1.0.9 | 2026-04-21T06:58:08.016Z | user\n\nVersion 1.0.9\n\n- Added clarification about auth:login: now documents that most configuration is set automatically, and explains what to do if some fields are not set (saved.defaultProject/defaultWorkspace).\n- Added a new command: canvas:node:prompt, for parsing @ image/video placeholders in prompt text in nodes.\n- Provided a detailed list of editing commands that auto-save and explicitly advise not to call canvas:save after these operations.\n- Improved core usage instructions and error-handling explanation.\n- No code changes; documentation enhancements only.\n\nv1.0.8 | 2026-04-15T14:53:09.447Z | user\n\nNo file changes detected. No functional or documentation updates in this release.\n\nv1.0.7 | 2026-04-15T14:36:32.856Z | auto\n\n- Added a key notice: CLI JSON data is output to stdout only; debug/info logs go to stderr. For correct parsing, filter or ignore stderr when processing output.\n- Updated the `canvas:run` command description to clarify that `--wait` now performs built-in polling until completion (with a default 10 min timeout; recommend `--timeout 1800000` for video).\n- Enhanced task status query notes: `task:status` output now clearly states that valid output URLs are always in the `url` field, and `download_url` may be empty.\n- Updated the core workflow recommendation: now suggests the simpler `canvas:run --wait` method as the default approach for video generation. \n- Improved documentation for output handling and clarified recommended polling strategy for long-running tasks.\n\nv1.0.6 | 2026-04-15T13:59:39.809Z | user\n\nNo file changes detected for version 1.0.6.\n\n- No code or documentation updates in this release.\n- Functionality and interface remain unchanged from the previous version.\n\nv1.0.5 | 2026-04-15T13:02:32.983Z | user\n\n- Added support for new `wsHost` (WebSocket host) configuration in `auth:login` and `config` commands.\n- `auth:login` now automatically saves `wsHost` along with existing credentials.\n- Updated documentation regarding the treatment of `.canvas` suffix for paths and command usage.\n- Minor clarifications and improvements to configuration and workflow explanations.\n\nv1.0.4 | 2026-04-15T12:08:51.573Z | user\n\nVersion 1.0.4\n\n- Improved `auth:login`: now auto-saves `defaultProject` and `defaultWorkspace`, eliminating need for `config:set` after login.\n- When creating a canvas, `canvas:create` uses `defaultWorkspace` if `--path` is not specified.\n- Command guide and sample core workflow updated to reflect automatic project/workspace usage and simpler steps.\n- Updated configuration keys: now includes `defaultWorkspace`.\n- `auth:login` output now contains enriched metadata including project and workspace details.\n\nv1.0.3 | 2026-04-15T11:43:55.563Z | user\n\nv1.0.3 adds OpenClaw skill installation instructions and node类型/模型查询命令。\n\n- 文档新增“安装 OpenClaw Skill”指引，包含跳过安全扫描提示。\n- 新增“节点类型与模型查询”命令：`node:list`、`node:model`。\n- 编辑节点类型说明，支持列举和查询模型&枚举值。\n- 常用节点类型列表补充：文生图、视频编辑等。\n- 其余功能和命令无变动。\n\nv1.0.2 | 2026-04-15T10:47:28.786Z | user\n\n- 新增 `auth:login` 命令，可一键认证并自动保存 token、userId、username。\n- `auth:login` 支持可选 `--host`，方便切换不同后端环境。\n- 官方文档推荐优先用 `auth:login` 做认证，不再建议手动 `config:set mcpToken`。\n- 更新“核心流程”：在所有操作前增加认证步骤，并优化项目设置流程说明。\n- 命令速查部分补充 `auth:login` 和认证配置相关说明。\n\nv1.0.1 | 2026-04-15T07:43:21.962Z | user\n\n- Removed all homepage/host and environment switching documentation.\n- Updated configuration instructions: only `ZENVFX_MCP_TOKEN` and `ZENVFX_PROJECT` environment variables are referenced.\n- Removed host-related installation and config examples to streamline quickstart.\n- All command documentation and core workflow remain unchanged.\n- Metadata homepage field removed.\n\nv1.0.0 | 2026-04-15T07:40:01.780Z | user\n\nzenvfx-cli 1.0.0\n\n- Initial release of ZenVFX CLI for AI video creation and platform management.\n- Supports canvas, node, and file system management via command line.\n- Includes commands to create, edit, and run AI video workflows, with session-based canvas operations.\n- Full CLI output in JSON format for both success and error cases.\n- Installation instructions and core workflows provided in SKILL.md.\n- Requires Node.js >= 18 and MCP Token environment/config.\n\nArchive index:\n\nArchive v1.0.19: 3 files, 14998 bytes\n\nFiles: skill-card.md (2336b), SKILL.md (36903b), _meta.json (130b)\n\nFile v1.0.19:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n**架构原则（v3）**：\n- **万物皆批处理**：所有编辑操作均接收 JSON 数组 / 逗号分隔 ID 列表，无论操作 1 个还是 N 个对象，底层统一为批量调用。\n- **运行节点支持同步/异步双模式**：`canvas:run` 默认异步，加 `--wait` 进入同步模式（daemon 内部轮询直到所有节点 completed/failed 才返回）。\n- **Partial Success**：批量操作逐项执行，某项失败不影响其余，返回 `results` 数组逐项标注状态。\n\n---\n\n## 版本与升级\n\n- **当前最新版本**：`0.9.1`\n- **包名**：`@tencent/zenvfx-cli`\n- **Registry**：`https://mirrors.tencent.com/npm/`（腾讯内网 npm 镜像）\n\n### 安装 / 升级到最新\n\n```bash\n# 首次安装 或 升级到 registry 上的最新版（@latest 等价于不写 tag）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 升级到指定版本\nnpm install -g @tencent/zenvfx-cli@0.9.1 --registry https://mirrors.tencent.com/npm/\n```\n\n> 注意：必须带 `--registry`，公网 `registry.npmjs.org` 上没有这个包。\n\n### 如何确认已经是最新版\n\n按下面三步对比，三个版本号一致即说明已装到最新：\n\n```bash\n# 1. 本地已安装版本\nzenvfx --version\n# 输出形如：@tencent/zenvfx-cli/0.9.1 linux-x64 node-v20.x\n\n# 2. registry 上当前 latest 版本\nnpm view @tencent/zenvfx-cli version --registry=https://mirrors.tencent.com/npm/\n# 输出形如：0.9.1\n\n# 3. 全局安装包元信息（确认安装路径与版本，排除多版本污染）\nnpm ls -g @tencent/zenvfx-cli --registry=https://mirrors.tencent.com/npm/\n```\n\n若 `zenvfx --version` 比 `npm view` 拿到的版本旧，重新执行上面的 `npm install -g ...@latest` 即可；若 `zenvfx` 命令找不到，检查 `npm config get prefix` 下的 `bin` 是否在 `PATH` 里。\n\n升级后建议再跑一次 `zenvfx auth:verify <token>`，确认本地配置仍然可用。\n\n---\n\n## 认证与安装\n\n```bash\n# 安装（详见上一节\"版本与升级\"）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n\n# 仅校验 token（不切换默认项目/workspace）\nzenvfx auth:verify <token>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）\n```\n\n`project:switch` 自动解析 workspace 的规则（仅依赖 `userId`，不依赖 `username`，因为 username 是用户可自定义的别名）：\n1. **精确匹配**：`/{projectId}/用户空间/` 下目录名以 `_{userId}` 结尾\n2. **模糊匹配**：目录名包含 `userId`\n3. 均未命中则清空 `defaultWorkspace`，需手动设置\n\n也可手动设置：\n```bash\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `auth:verify <token>` | 仅校验 token 合法性并写入 `mcpToken`，不切换项目/workspace |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n| `project:list` | 列出项目 |\n| `project:switch <projectId>` | 切换项目（自动更新 defaultProject + defaultWorkspace，workspace 匹配仅依赖 `userId`，不依赖 `username`），可选 `--no-workspace` |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:id-to-path --id <id>` | 内部 ID 转路径 |\n| `file:upload --local-file <本地路径> --project-id <id> [--file-path <ZenFS路径>] [--title <名称>]` | 上传本地文件到 COS 并注册素材；`--file-path` 可省略（仅上传不写 ZenFS） |\n\n### 画布管理\n\n标注 `[S]` 的命令**必须携带 `--canvas <path>` 参数**。系统会根据 `--canvas` 路径**自动执行 `canvas:open`**（如果尚未打开），无需手动调用。\n\n> ⚠️ **`--data` / `--value-json` 的 JSON 值直接裸写，不加单引号或双引号包裹**。\n> 命令解析器使用空格切分（`split(/\\s+/)`），不支持引号转义。\n> - ✅ `--data [{\"type\":\"image_generator\"}]`\n> - ❌ `--data '[{\"type\":\"image_generator\"}]'`（单引号成为 JSON 值的一部分 → `JSON 解析失败`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布（不递归），可选 `--list-path` |\n| `canvas:open --canvas <path>` `[S]` | 显式打开画布（一般无需手动调用，其他 `[S]` 命令会自动触发） |\n| `canvas:info --canvas <path>` `[S]` | 查看画布信息 |\n| `canvas:save --canvas <path>` `[S]` | 保存画布（编辑命令已自动保存，通常不需要） |\n| `canvas:run --ids <id1,id2,...> --canvas <path>` `[S]` | 批量运行节点；默认异步立即返回 `query_hint`，加 `--wait` 进入同步模式 |\n\n#### canvas:run 同步/异步模式\n\n| 模式 | 触发 | 返回时机 | 适用场景 |\n|------|------|----------|----------|\n| **异步**（默认） | `canvas:run --ids ...` | 立即返回，含 `submitted`/`results[].taskId`/`query_hint` | 长链路、并发多节点；调用方按 `query_hint.command` 自行轮询 |\n| **同步** | `canvas:run --ids ... --wait` | 在 daemon 内部轮询直到全部 `completed`/`failed` 才返回最终结果（含 `outputs[].url`） | 单节点或短链路调试；脚本希望一次拿到结果 |\n\n- `--timeout <秒>` 仅在 `--wait` 时生效，默认 **1800（30 分钟）**。\n- 异步 IPC 超时按 `节点数 × 15s + 60s` 自动放宽，最低 120s。\n- 同步模式返回结构：\n  ```json\n  {\n    \"submitted\": true,\n    \"mode\": \"sync\",\n    \"timedOut\": false,\n    \"elapsed\": 62025,\n    \"results\": [\n      { \"taskId\": \"...\", \"status\": \"completed\", \"nodes\": [{ \"nodeId\": \"...\", \"status\": \"completed\", \"outputs\": [...], \"textOutputs\": [] }] }\n    ]\n  }\n  ```\n\n```bash\n# 同步等待两个图片节点跑完\nzenvfx canvas:run --ids image_generator-aaa,image_generator-bbb --wait --timeout 600 --canvas \"$CANVAS_PATH\"\n\n# 异步触发，自己轮询\nRUN=$(zenvfx canvas:run --ids node1,node2 --canvas \"$CANVAS_PATH\" 2>/dev/null)\n# 取 query_hint.command 后定期 zenvfx task:status ...\n```\n\n### 节点操作 `[S]`\n\n编辑类命令执行后**自动保存**画布。\n\n> ⚠️ **`--canvas` 是必填参数**：所有标注 `[S]` 的命令都**必须**携带 `--canvas <path>` 参数指定画布路径（或通过环境变量 `ZENVFX_CANVAS` 提供）。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list --canvas <path>` | 列出所有节点 |\n| `canvas:node:info --ids <id1,id2> --canvas <path>` | 批量查看节点详情（pins、options、taskId/taskStatus） |\n| `canvas:node:add --data <JSON数组> --canvas <path>` | 批量添加节点 |\n| `canvas:node:remove --ids <id1,id2> --canvas <path>` | 批量删除节点 |\n| `canvas:node:set --data <JSON数组> --canvas <path>` | 批量设置节点参数 |\n| `canvas:node:set --id <id> --option <name> --value <val> --canvas <path>` | 快捷模式：单节点单参数设置 |\n| `canvas:node:move --data <JSON数组> --canvas <path>` | 批量移动节点位置 |\n| `canvas:node:move --id <id> --position <x,y> --canvas <path>` | 快捷模式：单节点移动 |\n| `canvas:node:prompt --id <id> --prompt <text> --canvas <path>` | 解析 prompt 中的 @占位符（如 `@首帧图1`），可选 `--model` |\n| `node:model <nodeTypes>` | 查询节点支持的模型与参数枚举（支持逗号分隔多个类型） |\n| `node:list` | 列出所有可用节点类型定义（本地，不需网络） |\n| `node:defs` | 一站式返回所有节点完整定义（本地 schema + 后端模型/参数），AI Agent 加载节点知识首选 |\n\n#### 参数校验错误提示（节点命令通用）\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `--data` JSON 解析失败 | `--data JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `--data` 不是非空数组 | `--data 必须是非空 JSON 数组` | `INVALID_JSON` |\n| `node:add` 缺少 type | `参数校验失败: data[N].type 是必填项` | `MISSING_VALUE` |\n| `node:set` 批量模式缺少 id | `参数校验失败: data[N].id 是必填项` | `MISSING_VALUE` |\n| `node:set` 批量模式 options 不是对象 | `参数校验失败: data[N].options 必须是对象` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少 --id | `参数校验失败: 必须提供 --data（批量模式）或 --id + --option + --value（快捷模式）` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少 --option | `参数校验失败: 快捷模式需要 --option 指定选项名称` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少值 | `参数校验失败: 快捷模式必须提供 --value 或 --value-json` | `MISSING_VALUE` |\n| `--value-json` JSON 解析失败 | `--value-json JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `node:info/remove` --ids 为空 | `参数校验失败: --ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n| `node:move` 批量缺少 nodeId/position | `参数校验失败: data[N].nodeId 是必填项` / `data[N].position 是必填项` | `MISSING_VALUE` |\n| `node:move` 快捷模式缺少 --id 或 --position | `参数校验失败: 快捷模式需要 --position 指定目标位置` | `MISSING_VALUE` |\n\n#### canvas:node:add --data 格式\n\n```json\n[\n  {\n    \"type\": \"string\",     // [必填] 节点类型，如 \"image_generator\", \"normal_video_generator\"\n    \"name\": \"string\",     // [选填] 节点名称\n    \"position\": \"string\", // [选填] 坐标位置，如 \"100,200\"，默认 \"0,0\"\n    \"options\": {}         // [选填] 节点配置参数（如 prompt, model, clarity, ratio, duration 等），\n                          //        创建后立即设置，无需再单独调用 canvas:node:set\n  }\n]\n```\n\n**示例**：\n```bash\n# 基础：只创建节点\nzenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"position\":\"0,0\"},{\"type\":\"image_input\",\"position\":\"400,0\",\"name\":\"首帧图\"}] --canvas \"$CANVAS_PATH\"\n\n# 带 options：创建并设置参数（省去 canvas:node:set）\nzenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"name\":\"文生视频\",\"position\":\"0,0\",\"options\":{\"prompt\":\"傍晚海边小孩嬉戏\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}}] --canvas \"$CANVAS_PATH\"\n```\n\n#### canvas:node:set 两种模式（互斥）\n\n**模式 1 — 批量模式 `--data`**（多节点多参数）：\n```json\n[\n  {\n    \"id\": \"string\",       // [必填] 节点 ID\n    \"options\": {           // [必填] 要设置的参数对象\n      \"prompt\": \"赛博朋克\",\n      \"model\": \"kling-video-o1\"\n    }\n  }\n]\n```\n```bash\nzenvfx canvas:node:set --data [{\"id\":\"node1\",\"options\":{\"prompt\":\"赛博朋克\",\"model\":\"kling-video-o1\"}}] --canvas \"$CANVAS_PATH\"\n```\n\n**模式 2 — 快捷模式**（单节点单参数，LLM 友好，无需构造 JSON）：\n```bash\nzenvfx canvas:node:set --id node-abc --option prompt --value \"一只银渐层胖猫咪\" --canvas \"$CANVAS_PATH\"\n# JSON 值使用 --value-json\nzenvfx canvas:node:set --id node-abc --option config --value-json {\"width\":1024} --canvas \"$CANVAS_PATH\"\n```\n\n> ⚠️ `--data` 与 `--id + --option + --value` 互斥。传了 `--data` 则忽略快捷模式参数。\n\n#### canvas:node:move 两种模式（互斥）\n\n```bash\n# 批量\nzenvfx canvas:node:move --data [{\"nodeId\":\"n1\",\"position\":\"100,200\"},{\"nodeId\":\"n2\",\"position\":{\"x\":300,\"y\":400}}] --canvas \"$CANVAS_PATH\"\n\n# 快捷\nzenvfx canvas:node:move --id node-abc --position \"100,200\" --canvas \"$CANVAS_PATH\"\nzenvfx canvas:node:move --id node-abc --position {\"x\":100,\"y\":200} --canvas \"$CANVAS_PATH\"\n```\n\n> **节点位置**：添加多个节点时用 `position` 指定坐标，避免叠加。建议水平间隔 400px：`\"0,0\"`、`\"400,0\"`、`\"800,0\"`。\n\n### 打组操作 `[S]`\n\n> ⚠️ 同样**必须**携带 `--canvas <path>` 参数。所有写操作执行后**自动保存**。\n>\n> **打组必须一次做到完整收尾**：当用户要求\"打组/分组/整理成组\"时，优先只调用 `canvas:node:group`。该命令内部会自动完成：创建组 → 对新组/受影响父组执行组排序 → 检查顶层重叠 → 必要时整体平移避免重叠。不要在打组后停在\"已创建组\"，需根据返回的 `sortedGroups` / `overlapCheck` 确认布局已收尾；只有用户明确要求重新排序某个已有组时，才额外调用 `canvas:node:group:sort`。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:group --node-ids <id1,id2,...> [--name <name>] --canvas <path>` | 将一批节点打包为新组（自动剥离原父组成员、自动派生组的边/实体引用，并自动排序/检查重叠/必要时避让） |\n| `canvas:node:ungroup --group-id <id> --canvas <path>` | 解散组，成员上浮到父级 |\n| `canvas:node:group:info --group-id <id> --canvas <path>` | 查询组信息（id/name/members/color/bounds，**只读**） |\n| `canvas:node:group:members --group-id <id> --node-ids <id1,id2,...> --canvas <path>` | 全量替换组成员，自动重派生 edges/entities |\n| `canvas:node:group:color --group-id <id> --color <颜色> --canvas <path>` | 修改组颜色标签，可选值：`gray` / `red` / `orange` / `yellow` / `green` / `cyan` / `blue` / `purple` / `none`（清除颜色） |\n| `canvas:node:group:sort --group-id <id> --canvas <path>` | 对组内节点执行依赖流自动排序布局（基于内部边自动调整位置） |\n| `canvas:node:group:execute --group-id <id> --canvas <path>` | 按依赖顺序执行组内所有可执行节点（异步触发，进度通过 `task:status` 查询） |\n| `canvas:node:group:cancel --group-id <id> --canvas <path>` | 取消组的按序执行（停止组内所有进行中或 pending 的子节点） |\n\n**示例**：\n\n```bash\n# 1. 把 3 个节点打成一个组并命名（自动完成组排序 + 顶层重叠检查/避让）\nzenvfx canvas:node:group --node-ids n1,n2,n3 --name \"场景A\" --canvas \"$CANVAS_PATH\"\n# → { groupId: \"group_xxx\", status: \"ok\", sortedGroups: [...], overlapCheck: { checked, movedGroups, overlapsBefore, overlapsAfter } }\n\n# 2. 查询组详情\nzenvfx canvas:node:group:info --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 3. 改颜色 / 清除颜色\nzenvfx canvas:node:group:color --group-id group_xxx --color blue --canvas \"$CANVAS_PATH\"\nzenvfx canvas:node:group:color --group-id group_xxx --color none --canvas \"$CANVAS_PATH\"\n\n# 4. 改成员（全量替换）\nzenvfx canvas:node:group:members --group-id group_xxx --node-ids n1,n4 --canvas \"$CANVAS_PATH\"\n\n# 5. 组内自动排序\nzenvfx canvas:node:group:sort --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 6. 按依赖顺序执行组内节点（异步）\nzenvfx canvas:node:group:execute --group-id group_xxx --canvas \"$CANVAS_PATH\"\n# 查进度：zenvfx task:status --ids <taskIds> --canvas-id <canvasId>\n\n# 7. 取消执行\nzenvfx canvas:node:group:cancel --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 8. 解散\nzenvfx canvas:node:ungroup --group-id group_xxx --canvas \"$CANVAS_PATH\"\n```\n\n**参数校验错误提示（打组命令）**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `--node-ids` 为空 | `参数校验失败: --node-ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n| 任一 nodeId 不存在 | `Node not found: <id>` | `NODE_NOT_FOUND` |\n| `--group-id` 对应节点不是 group 类型 | `Node <id> is not a group` | `NODE_VALIDATION_FAILED` |\n| `groupNodes` 归一化后成员为空 | `No valid nodes to group` | `NODE_VALIDATION_FAILED` |\n| `--color` 取值非法 | 由 oclif options 拒绝并列出可选值 | — |\n\n> 💡 **打组语义提示**：\n> - `canvas:node:group` 的 `--node-ids` **可以混合普通节点和已有的组**。当传入的节点是另一个组的成员时，工具会自动从原父组中剥离，避免重复归属。\n> - `canvas:node:group` 默认会自动执行布局收尾：排序新组/受影响父组，并检查顶层重叠；若 `overlapCheck.overlapsAfter > 0`，需要继续使用 `canvas:node:move` 或再次组织布局，不能直接宣称布局完美。\n> - `canvas:node:group:members` 是**全量替换**而非增量；想加成员请先 `info` 查出当前 members，合并后再传入。\n> - `canvas:node:group:sort` 仅对组的**直接成员**做布局，不会递归子组内部；普通打组场景无需再额外调用，因为 `canvas:node:group` 已自动收尾。\n\n### 连线操作 `[S]`\n\n> ⚠️ 同样**必须**携带 `--canvas <path>` 参数。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list --canvas <path>` | 列出所有连线 |\n| `canvas:edge:add --data <JSON数组> --canvas <path>` | 批量连接节点 |\n| `canvas:edge:remove --ids <id1,id2> --canvas <path>` | 批量删除连线 |\n\n#### canvas:edge:add --data 格式\n\n```json\n[\n  {\n    \"source\": \"string\",        // [必填] 源节点 ID\n    \"sourceHandle\": \"string\",  // [必填] 源节点输出 handle（pinName）\n    \"target\": \"string\",        // [必填] 目标节点 ID\n    \"targetHandle\": \"string\"   // [必填] 目标节点输入 handle（pinName）\n  }\n]\n```\n\n**示例**：\n```bash\nzenvfx canvas:edge:add --data [{\"source\":\"n1\",\"sourceHandle\":\"output\",\"target\":\"n2\",\"targetHandle\":\"ref_images\"}] --canvas \"$CANVAS_PATH\"\n```\n\n**参数校验错误提示（连线命令）**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `edge:add` JSON 解析失败 | `--data JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `edge:add` 不是非空数组 | `--data 必须是非空 JSON 数组` | `INVALID_JSON` |\n| `edge:add` 缺少必填字段 | `参数校验失败: data[N].source 是必填项` 等 | `MISSING_VALUE` |\n| `edge:remove` --ids 为空 | `参数校验失败: --ids 至少需要包含一个边 ID` | `MISSING_VALUE` |\n\n### 任务查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `task:status --ids <taskId1,taskId2> --canvas-id <id>` | 批量查询任务状态（`--ids` 和 `--canvas-id` 均为必填） |\n\n**查询命令参数校验**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `node:model` 未提供 nodeType | `参数校验失败: nodeTypes 是必填项，请提供至少一个节点类型` | `MISSING_VALUE` |\n| `node:model` 未知类型 | `未知的节点类型: <xxx>`（返回 validTypes 列表，不中断） | — |\n| `task:status` --ids 为空 | `参数校验失败: --ids 至少需要包含一个任务 ID` | `MISSING_VALUE` |\n| `task:status` project 未配置 | `参数校验失败: project 未配置，请通过 auth:login 或 config:set defaultProject 设置` | `MISSING_CONFIG` |\n| `canvas:run` --ids 为空 | `参数校验失败: --ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`sourceHandle` 和 `targetHandle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:set`、`canvas:node:move`、`canvas:edge:add`、`canvas:edge:remove`、`canvas:node:group*` 系列执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n> 注：旧版的 `canvas:node:props` 已下线，统一通过 `canvas:node:set` 设置参数。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n### 4. canvas:open 一般无需手动调用\n\n所有 `[S]` 命令在执行时会**自动按 `--canvas` 路径打开/复用 Session**。只有在你需要显式预热 daemon、提前感知错误时才调用 `canvas:open`。\n\n### 5. 批量传参约定（多 ID / 多对象）\n\nCLI 对\"多个对象\"的批量传参分两种风格，**不混用**：\n\n| 风格 | 适用命令 | 用法 |\n|------|----------|------|\n| `--ids` 逗号分隔 | `canvas:run` / `canvas:node:remove` / `canvas:node:info` / `task:status` 等\"只需要 ID\"的命令 | `--ids \"n1,n2,n3\"`，逗号两侧空格会被 trim，空段会被过滤 |\n| `--data` JSON 数组 | `canvas:node:add` / `canvas:node:set` / `canvas:edge:add` / `canvas:edge:remove` 等\"需要传字段\"的命令 | `--data '[{...},{...}]'`，每项校验必填字段，partial success |\n\n> 升级 CLI 后建议 `daemon:stop` 一次，避免老 daemon 仍按旧协议解析参数（详见\"已知问题 #1\"）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```\n0. auth:login <token>                                      （一次性）\n1. canvas:create --name \"xxx\"                              （自动使用 defaultWorkspace）\n2. canvas:node:add --data [{\"type\":\"normal_video_generator\",\"position\":\"0,0\",\"options\":{\"prompt\":\"...\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\"}}] --canvas \"${CANVAS_PATH}\"\n3. 选 A 或 B 运行：\n   A. 同步：canvas:run --ids $NODE_ID --wait --timeout 600 --canvas \"${CANVAS_PATH}\"\n      → 阻塞返回最终 outputs，最简单\n   B. 异步：canvas:run --ids $NODE_ID --canvas \"${CANVAS_PATH}\"\n      → 立即返回 query_hint，再用 task:status 轮询\n```\n\n### 同步 vs 异步选择\n\n| 场景 | 推荐 |\n|------|------|\n| 单节点 / 短链路 / 想\"一行命令拿结果\" | `canvas:run --wait --timeout 600` |\n| 多节点并发触发，调用方自己控制轮询节奏 | 默认异步 + `task:status` |\n| LLM Agent 想避免长时间阻塞主进程 | 默认异步，把 `query_hint` 保存到任务上下文 |\n| 在 shell 脚本里串联多个步骤 | `--wait` 更直观；超时按节点类型设置（图片 300s、视频 1800s） |\n\n### 异步轮询最佳实践\n\n异步模式 `canvas:run` 立即返回，结果中包含 `query_hint`：\n\n```json\n{\n  \"submitted\": true,\n  \"mode\": \"async\",\n  \"results\": [\n    { \"nodeId\": \"node1\", \"taskId\": \"abc1234\", \"status\": \"pending\" }\n  ],\n  \"query_hint\": {\n    \"command\": \"task:status --ids abc1234 --canvas-id xxx\",\n    \"instruction\": \"请使用上述命令批量查询任务结果，建议间隔 15s\"\n  }\n}\n```\n\n**轮询步骤**：\n\n1. `canvas:run --ids <nodeId1,nodeId2>` — 立即返回 `results` 和 `query_hint`\n2. 直接执行 `query_hint.command`（已自动拼接所有 taskId）\n3. 每 **15 秒**轮询一次 `task:status --ids <taskIds> --canvas-id <canvasId>`\n4. 当所有任务 `status` 为 `completed` / `failed` 时停止，最长 **30 分钟**\n\n> `outputs` 中有效 URL 在 `url` 字段（带 COS 签名），`download_url` 可能为空。\n\n### 完整示例（同步等待版）\n\n```bash\n# 0. 认证\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 批量添加节点（canvas:open 自动执行，无需手动调用）\nRESULT=$(zenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"name\":\"文生视频\",\"position\":\"0,0\",\"options\":{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}}] --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 3. 同步运行（阻塞等待最终结果）\nzenvfx canvas:run --ids $NODE_ID --wait --timeout 1200 --canvas \"${CANVAS_PATH}\"\n```\n\n### 完整示例（异步轮询版）\n\n```bash\n# 1~2 同上\n\n# 3. 异步运行\nRUN_RESULT=$(zenvfx canvas:run --ids $NODE_ID --canvas \"${CANVAS_PATH}\" 2>/dev/null)\n# 从 query_hint 获取轮询命令\nQUERY_CMD=$(echo $RUN_RESULT | grep -o '\"command\":\"[^\"]*\"' | head -1 | sed 's/\"command\":\"//;s/\"$//')\n\n# 4. 轮询任务状态（每 15s 一次）\nwhile true; do\n  STATUS=$(zenvfx $QUERY_CMD 2>/dev/null)\n  if echo \"$STATUS\" | grep -qE '\"status\":\"(completed|failed)\"'; then\n    echo \"$STATUS\"\n    break\n  fi\n  sleep 15\ndone\n```\n\n---\n\n## 节点参数\n\n> **重要**：model/clarity/ratio/duration 的值**必须通过 `node:model <nodeType>` 或 `node:defs` 动态查询**，不要硬编码。\n\n> **视频节点建议**：模型 `kling` + 分辨率 `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n> **node:model 支持批量查询**：`node:model normal_video_generator,image_generator` 一次返回多个类型的模型列表。\n\n> **node:defs 一站式知识**：`node:defs` 同时返回本地 schema（pin/option）+ 后端模型枚举/参数，AI Agent 启动期一次拉取即可，避免后续多次往返。\n\n通过 `--data` 批量模式或 `--option` + `--value` 快捷模式传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n**节点类型**（`type` 必须是下列英文 snake_case 枚举之一，写错会报 `NODE_TYPE_INVALID`）：\n\n| `type` | 说明 |\n|--------|------|\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点（⚠️ **文本节点是 `text_input`，不是 `text`**） |\n| `image_generator` | 文/图生图 |\n| `normal_video_generator` | 文/图生视频 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 |\n| `comprehensive_reference_generator` | 全能参考生视频 |\n| `llm` | 大模型文本节点 |\n| `group` | 组节点 |\n| `video_process` | 视频处理（变速/帧率转换/冻帧延长/裁切） |\n| `frame_extraction` | 视频截帧 |\n\n> 中文（\"提示词\"、\"文本\"）是节点 `label`，不是 `type`，传给 `canvas:node:add` 的 `--data` 中会直接失败。\n\n### Prompt 占位符\n\nPrompt 中可以用 `@` 前缀引用**上游节点通过连线传入的输入资源**。占位符直接写在 `canvas:node:set` 的 prompt 值中即可，画布引擎运行时会自动解析。\n\n**支持的占位符**（数字后缀可选，默认 1，如 `@提示词` 等价于 `@提示词1`）：\n\n| 占位符 | 含义 | 上游节点类型 |\n|--------|------|------------|\n| `@提示词1`、`@提示词2`… | 引用上游 **文本节点** 的文本内容 | `text_input` / `llm` |\n| `@参考图`、`@参考图1`… | 引用上游 **图片节点** 的图片 | `image_input` / `image_generator` |\n| `@首帧图1`、`@首帧图2`… | 引用首帧参考图 | `image_input` / `image_generator` |\n| `@尾帧图1`、`@尾帧图2`… | 引用尾帧参考图 | `image_input` / `image_generator` |\n| `@参考视频`、`@参考视频1`… | 引用上游 **视频节点** 的视频 | `video_input` / 视频生成节点 |\n| `@参考音频`、`@参考音频1`… | 引用上游 **音频节点** 的音频 | `audio_input` |\n\n**`@提示词` 引用上游文本节点**（最常用）：\n\n用 `text_input` 节点写好提示词文本，连线到生成节点的\"提示词\"输入口，然后在 prompt 中用 `@提示词1` 引用。画布引擎运行时会**直接替换为上游文本节点的文本内容**。\n\n```bash\n# text_input 节点（id=text-001）prompt 值为 \"傍晚海边小孩嬉戏\"\n# 连线：text-001 → video-001 的\"提示词1\"输入口\nzenvfx canvas:node:set --id video-001 --option prompt --value \"帮我生成一段视频：@提示词1\" --canvas \"$CANVAS_PATH\"\n```\n\n**图片/视频/音频占位符**：\n\n同样直接写在 prompt 中，画布引擎运行时会根据模型自动转换为对应格式。\n\n```bash\nzenvfx canvas:node:set --id $VIDEO_NODE_ID --option prompt --value \"小孩奔向海浪@首帧图1，夕阳洒在海面@尾帧图1\" --canvas \"$CANVAS_PATH\"\n```\n\n> 想看模型最终拿到的 prompt 字面值？先用 `canvas:node:prompt --id <id> --prompt \"<原文>\" [--model <id>]` 预览解析结果。\n\n---\n\n## 批量返回格式说明\n\n编辑类操作均返回 Partial Success 格式：\n\n```json\n{\n  \"results\": [\n    { \"status\": \"ok\", \"id\": \"xxx\", \"type\": \"image_generator\", \"name\": \"生图节点\", \"position\": { \"x\": 0, \"y\": 0 } },\n    { \"status\": \"error\", \"id\": null, \"type\": \"unknown_type\", \"error\": \"NODE_TYPE_INVALID\" }\n  ],\n  \"successCount\": 1,\n  \"failCount\": 1\n}\n```\n\n- 批量操作中某项失败**不影响**其余项\n- 每项通过 `status` 字段标注 `\"ok\"` / `\"error\"`\n- 顶层返回 `successCount` / `failCount` 汇总\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | `auth:verify <token>` 或重新 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败（server overload） | 系统已内置重试 3 次（间隔 1s/2s/3s），仍失败则手动重试 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `NODE_TYPE_INVALID` | 节点类型不合法 | 用 `text_input` / `image_input` / `video_input` / `audio_input` / `image_generator` / `normal_video_generator` / `first_to_last_video_generator` / `composite_video_generator` / `comprehensive_reference_generator` / `llm` / `group` / `video_process` / `frame_extraction`；中文标签不是 `type` |\n| `INVALID_JSON` | `--data` / `--value-json` JSON 解析失败 | 检查引号、逗号、括号等 JSON 格式 |\n| `MISSING_VALUE` | 必填字段缺失 | 查看报错信息中标注的缺失字段（如 `data[0].type 是必填项`） |\n| `MISSING_CONFIG` | 配置缺失（project 等） | 通过 `auth:login` 或 `config:set defaultProject` 设置 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --ids <id>` 查看可用选项 |\n| `EDGE_HANDLE_INVALID` | 连线 handle 不合法 | `canvas:node:info --ids <id>` 查看 inputPins/outputPins |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试；若启动直接超时见下文\"已知问题 #2 react 缺失\" |\n| `DAEMON_START_FAILED` | daemon 启动失败 | 检查端口占用，清理后重试 |\n| `DAEMON_CONNECTION_FAILED` | daemon 连接失败 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数，重跑 `node:model <类型>` 对齐参数 |\n| `UPLOAD_TOKEN_FAILED` / `UPLOAD_FAILED` / `REGISTER_ASSET_FAILED` | `file:upload` 各阶段失败（已内置 3 次重试） | 查 `error.message` 与 details；多为网络/凭证问题，过段时间重试 |\n| `NETWORK_ERROR` | 网络错误 | 检查网络连接，确认 host 配置 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\n**调试运行节点的请求体**（对照网页协议时常用）：\n\ndaemon 会把每次提交后端的 `submitTask` 请求体写到 `~/.config/zenvfx/daemon.log`。可用脚本快速取最近一次：\n\n```bash\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh           # 最近 1 次\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh 3         # 最近 3 次\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh 1 image_generator-xxx   # 按关键词过滤\n```\n\n---\n\n## 已知问题与坑位（v0.9.1）\n\n> 这里收录已经踩过的\"行为不符合预期 / 必须绕过\"的问题。修复后请同步移除对应条目。\n\n### 1. CLI 升级后 `canvas:run --ids \"a,b\"` 报 `nodeId is required`（**版本错位，不是 bug**）\n\n- **现象**：升级到 0.9.1 后，`zenvfx canvas:run --ids \"node1,node2\"` 报 `MISSING_VALUE: nodeId is required`。\n- **根因**：CLI 二进制升级了，但**老版本 daemon 进程还在跑**——\n  - 0.9.1 CLI 走新协议送 `nodeIds: ['node1','node2']`\n  - 0.9.0 daemon 仍按旧协议解构单个 `nodeId`，自然为空\n  - 报错文案是判断依据：0.9.1 应是 `nodeIds (string[]) is required`，旧文案是 `nodeId is required`\n- **正解**：升级 CLI 后强制重启 daemon——\n  ```bash\n  zenvfx daemon:stop\n  zenvfx daemon:status     # 会自动拉起新版本 daemon\n  zenvfx canvas:run --ids \"node1,node2\" --canvas /proj/canvas   # 此时正常\n  ```\n- **建议**：每次 `npm install -g @tencent/zenvfx-cli@latest` 后顺手 `daemon:stop` 一次。\n\n\n### 2. daemon 启动报 `DAEMON_TIMEOUT`，日志缺 `react` 模块\n\n- **现象**：`daemon:stop` 后重启 daemon 直接超时，`~/.config/zenvfx/daemon.log` 显示类似：\n  ```\n  Error: Cannot find module 'react'\n      at zustand/react.js\n  ```\n- **根因**：0.9.1 daemon 用 `zustand` 管状态，`zustand/index.js` 间接 import 了 `zustand/react.js`，但打包时未把 `react` 作为 bundled 依赖打入；Node.js 端无 `react` 即启动失败。\n- **绕过**：在全局 CLI 安装目录手动补一个 `react` 即可——\n  ```bash\n  # 找到全局安装目录\n  npm root -g\n  # 进入 CLI 包目录补 react（版本不敏感，挂个 18 即可）\n  cd \"$(npm root -g)/@tencent/zenvfx-cli\"\n  npm install react@18 --no-save --registry=https://mirrors.tencent.com/npm/\n\n  # 重启 daemon 验证\n  zenvfx daemon:stop\n  zenvfx daemon:status\n  ```\n- **彻底修复方向**（待发版）：在 `zenvfx-cli` 的 esbuild 配置里把 `zustand/react` 标为 external 或换用 `zustand/vanilla`，避免引入 react。\n\n### 3. `file:id-to-path` 返回路径多拼了\"项目名\"层级\n\n- **现象**：\n  ```bash\n  zenvfx file:id-to-path --id <fileId>\n  # 返回:  /d6683tdk40pqu9ruglp0/内部项目体验/用户空间/李智_4866893/xxx\n  # 实际:  /d6683tdk40pqu9ruglp0/用户空间/李智_4866893/xxx\n  ```\n- **根因**：`file:id-to-path` 在 projectId 之后多拼了项目名（如\"内部项目体验\"），与 VFS 实际路径结构不一致。直接用此路径调用 `canvas:*` / `file:stat` 会得到 `CANVAS_NOT_FOUND` / `FILE_NOT_FOUND`。\n- **绕过**：用 `file:readdir` 反查真实路径——\n  ```bash\n  zenvfx file:readdir --path \"/<projectId>/用户空间/<userDir>\" 2>/dev/null\n  # 或先 file:stat 探测两种路径，哪条 ok 用哪条\n  ```\n- **修复方向**（待发版）：`file:id-to-path` 拼接时去掉项目名层级，与 `file:readdir` / `file:stat` 路径口径对齐。\n\nFile v1.0.19:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.19\",\n  \"publishedAt\": 1781593386861\n}\n\nFile v1.0.19:skill-card.md\n\n## Description:\n\nUse this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[lenzli](https://clawhub.ai/user/lenzli)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and creative operators use this skill to guide agents through ZenVFX CLI setup, authentication, canvas management, node editing, task execution, and troubleshooting for AI video workflows.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill installs and relies on a global ZenVFX CLI package from the Tencent registry.\n\nMitigation: Install only from a trusted registry source and prefer a pinned CLI version for repeatable deployments.\n\nRisk: The skill uses a ZenVFX token for authentication.\n\nMitigation: Use least-privilege, rotatable tokens and avoid entering tokens where shell history or logs may capture them.\n\nRisk: The documented CLI workflows can modify or delete ZenVFX project files, canvases, nodes, and edges.\n\nMitigation: Review proposed commands before execution and require explicit confirmation before delete operations such as file or node removal.\n\nRisk: Known CLI or daemon version mismatches can cause execution failures after upgrades.\n\nMitigation: Restart the daemon after CLI upgrades and verify the installed CLI version before running video generation workflows.\n\n## Reference(s):\n\n- [ZenVFX CLI ClawHub skill page](https://clawhub.ai/lenzli/skills/zenvfx-cli)\n- [lenzli ClawHub publisher profile](https://clawhub.ai/user/lenzli)\n- [Tencent npm registry](https://mirrors.tencent.com/npm/)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration, Code, JSON]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Guidance is oriented around ZenVFX CLI commands that return JSON on stdout.]\n\n## Skill Version(s):\n\n1.0.19 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.0.18: 3 files, 13542 bytes\n\nFiles: skill-card.md (2451b), SKILL.md (33144b), _meta.json (130b)\n\nFile v1.0.18:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n**架构原则（v3）**：\n- **万物皆批处理**：所有编辑操作均接收 JSON 数组 / 逗号分隔 ID 列表，无论操作 1 个还是 N 个对象，底层统一为批量调用。\n- **运行节点支持同步/异步双模式**：`canvas:run` 默认异步，加 `--wait` 进入同步模式（daemon 内部轮询直到所有节点 completed/failed 才返回）。\n- **Partial Success**：批量操作逐项执行，某项失败不影响其余，返回 `results` 数组逐项标注状态。\n\n---\n\n## 版本与升级\n\n- **当前最新版本**：`0.9.1`\n- **包名**：`@tencent/zenvfx-cli`\n- **Registry**：`https://mirrors.tencent.com/npm/`（腾讯内网 npm 镜像）\n\n### 安装 / 升级到最新\n\n```bash\n# 首次安装 或 升级到 registry 上的最新版（@latest 等价于不写 tag）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 升级到指定版本\nnpm install -g @tencent/zenvfx-cli@0.9.1 --registry https://mirrors.tencent.com/npm/\n```\n\n> 注意：必须带 `--registry`，公网 `registry.npmjs.org` 上没有这个包。\n\n### 如何确认已经是最新版\n\n按下面三步对比，三个版本号一致即说明已装到最新：\n\n```bash\n# 1. 本地已安装版本\nzenvfx --version\n# 输出形如：@tencent/zenvfx-cli/0.9.1 linux-x64 node-v20.x\n\n# 2. registry 上当前 latest 版本\nnpm view @tencent/zenvfx-cli version --registry=https://mirrors.tencent.com/npm/\n# 输出形如：0.9.1\n\n# 3. 全局安装包元信息（确认安装路径与版本，排除多版本污染）\nnpm ls -g @tencent/zenvfx-cli --registry=https://mirrors.tencent.com/npm/\n```\n\n若 `zenvfx --version` 比 `npm view` 拿到的版本旧，重新执行上面的 `npm install -g ...@latest` 即可；若 `zenvfx` 命令找不到，检查 `npm config get prefix` 下的 `bin` 是否在 `PATH` 里。\n\n升级后建议再跑一次 `zenvfx auth:verify <token>`，确认本地配置仍然可用。\n\n---\n\n## 认证与安装\n\n```bash\n# 安装（详见上一节\"版本与升级\"）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n\n# 仅校验 token（不切换默认项目/workspace）\nzenvfx auth:verify <token>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）\n```\n\n`project:switch` 自动解析 workspace 的规则（仅依赖 `userId`，不依赖 `username`，因为 username 是用户可自定义的别名）：\n1. **精确匹配**：`/{projectId}/用户空间/` 下目录名以 `_{userId}` 结尾\n2. **模糊匹配**：目录名包含 `userId`\n3. 均未命中则清空 `defaultWorkspace`，需手动设置\n\n也可手动设置：\n```bash\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `auth:verify <token>` | 仅校验 token 合法性并写入 `mcpToken`，不切换项目/workspace |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n| `project:list` | 列出项目 |\n| `project:switch <projectId>` | 切换项目（自动更新 defaultProject + defaultWorkspace，workspace 匹配仅依赖 `userId`，不依赖 `username`），可选 `--no-workspace` |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:id-to-path --id <id>` | 内部 ID 转路径 |\n| `file:upload --local-file <本地路径> --project-id <id> [--file-path <ZenFS路径>] [--title <名称>]` | 上传本地文件到 COS 并注册素材；`--file-path` 可省略（仅上传不写 ZenFS） |\n\n### 画布管理\n\n标注 `[S]` 的命令**必须携带 `--canvas <path>` 参数**。系统会根据 `--canvas` 路径**自动执行 `canvas:open`**（如果尚未打开），无需手动调用。\n\n> ⚠️ **`--data` / `--value-json` 的 JSON 值直接裸写，不加单引号或双引号包裹**。\n> 命令解析器使用空格切分（`split(/\\s+/)`），不支持引号转义。\n> - ✅ `--data [{\"type\":\"image_generator\"}]`\n> - ❌ `--data '[{\"type\":\"image_generator\"}]'`（单引号成为 JSON 值的一部分 → `JSON 解析失败`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布（不递归），可选 `--list-path` |\n| `canvas:open --canvas <path>` `[S]` | 显式打开画布（一般无需手动调用，其他 `[S]` 命令会自动触发） |\n| `canvas:info --canvas <path>` `[S]` | 查看画布信息 |\n| `canvas:save --canvas <path>` `[S]` | 保存画布（编辑命令已自动保存，通常不需要） |\n| `canvas:run --ids <id1,id2,...> --canvas <path>` `[S]` | 批量运行节点；默认异步立即返回 `query_hint`，加 `--wait` 进入同步模式 |\n\n#### canvas:run 同步/异步模式\n\n| 模式 | 触发 | 返回时机 | 适用场景 |\n|------|------|----------|----------|\n| **异步**（默认） | `canvas:run --ids ...` | 立即返回，含 `submitted`/`results[].taskId`/`query_hint` | 长链路、并发多节点；调用方按 `query_hint.command` 自行轮询 |\n| **同步** | `canvas:run --ids ... --wait` | 在 daemon 内部轮询直到全部 `completed`/`failed` 才返回最终结果（含 `outputs[].url`） | 单节点或短链路调试；脚本希望一次拿到结果 |\n\n- `--timeout <秒>` 仅在 `--wait` 时生效，默认 **1800（30 分钟）**。\n- 异步 IPC 超时按 `节点数 × 15s + 60s` 自动放宽，最低 120s。\n- 同步模式返回结构：\n  ```json\n  {\n    \"submitted\": true,\n    \"mode\": \"sync\",\n    \"timedOut\": false,\n    \"elapsed\": 62025,\n    \"results\": [\n      { \"taskId\": \"...\", \"status\": \"completed\", \"nodes\": [{ \"nodeId\": \"...\", \"status\": \"completed\", \"outputs\": [...], \"textOutputs\": [] }] }\n    ]\n  }\n  ```\n\n```bash\n# 同步等待两个图片节点跑完\nzenvfx canvas:run --ids image_generator-aaa,image_generator-bbb --wait --timeout 600 --canvas \"$CANVAS_PATH\"\n\n# 异步触发，自己轮询\nRUN=$(zenvfx canvas:run --ids node1,node2 --canvas \"$CANVAS_PATH\" 2>/dev/null)\n# 取 query_hint.command 后定期 zenvfx task:status ...\n```\n\n### 节点操作 `[S]`\n\n编辑类命令执行后**自动保存**画布。\n\n> ⚠️ **`--canvas` 是必填参数**：所有标注 `[S]` 的命令都**必须**携带 `--canvas <path>` 参数指定画布路径（或通过环境变量 `ZENVFX_CANVAS` 提供）。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list --canvas <path>` | 列出所有节点 |\n| `canvas:node:info --ids <id1,id2> --canvas <path>` | 批量查看节点详情（pins、options、taskId/taskStatus） |\n| `canvas:node:add --data <JSON数组> --canvas <path>` | 批量添加节点 |\n| `canvas:node:remove --ids <id1,id2> --canvas <path>` | 批量删除节点 |\n| `canvas:node:set --data <JSON数组> --canvas <path>` | 批量设置节点参数 |\n| `canvas:node:set --id <id> --option <name> --value <val> --canvas <path>` | 快捷模式：单节点单参数设置 |\n| `canvas:node:move --data <JSON数组> --canvas <path>` | 批量移动节点位置 |\n| `canvas:node:move --id <id> --position <x,y> --canvas <path>` | 快捷模式：单节点移动 |\n| `canvas:node:prompt --id <id> --prompt <text> --canvas <path>` | 解析 prompt 中的 @占位符（如 `@首帧图1`），可选 `--model` |\n| `node:model <nodeTypes>` | 查询节点支持的模型与参数枚举（支持逗号分隔多个类型） |\n| `node:list` | 列出所有可用节点类型定义（本地，不需网络） |\n| `node:defs` | 一站式返回所有节点完整定义（本地 schema + 后端模型/参数），AI Agent 加载节点知识首选 |\n\n#### 参数校验错误提示（节点命令通用）\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `--data` JSON 解析失败 | `--data JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `--data` 不是非空数组 | `--data 必须是非空 JSON 数组` | `INVALID_JSON` |\n| `node:add` 缺少 type | `参数校验失败: data[N].type 是必填项` | `MISSING_VALUE` |\n| `node:set` 批量模式缺少 id | `参数校验失败: data[N].id 是必填项` | `MISSING_VALUE` |\n| `node:set` 批量模式 options 不是对象 | `参数校验失败: data[N].options 必须是对象` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少 --id | `参数校验失败: 必须提供 --data（批量模式）或 --id + --option + --value（快捷模式）` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少 --option | `参数校验失败: 快捷模式需要 --option 指定选项名称` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少值 | `参数校验失败: 快捷模式必须提供 --value 或 --value-json` | `MISSING_VALUE` |\n| `--value-json` JSON 解析失败 | `--value-json JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `node:info/remove` --ids 为空 | `参数校验失败: --ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n| `node:move` 批量缺少 nodeId/position | `参数校验失败: data[N].nodeId 是必填项` / `data[N].position 是必填项` | `MISSING_VALUE` |\n| `node:move` 快捷模式缺少 --id 或 --position | `参数校验失败: 快捷模式需要 --position 指定目标位置` | `MISSING_VALUE` |\n\n#### canvas:node:add --data 格式\n\n```json\n[\n  {\n    \"type\": \"string\",     // [必填] 节点类型，如 \"image_generator\", \"normal_video_generator\"\n    \"name\": \"string\",     // [选填] 节点名称\n    \"position\": \"string\", // [选填] 坐标位置，如 \"100,200\"，默认 \"0,0\"\n    \"options\": {}         // [选填] 节点配置参数（如 prompt, model, clarity, ratio, duration 等），\n                          //        创建后立即设置，无需再单独调用 canvas:node:set\n  }\n]\n```\n\n**示例**：\n```bash\n# 基础：只创建节点\nzenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"position\":\"0,0\"},{\"type\":\"image_input\",\"position\":\"400,0\",\"name\":\"首帧图\"}] --canvas \"$CANVAS_PATH\"\n\n# 带 options：创建并设置参数（省去 canvas:node:set）\nzenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"name\":\"文生视频\",\"position\":\"0,0\",\"options\":{\"prompt\":\"傍晚海边小孩嬉戏\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}}] --canvas \"$CANVAS_PATH\"\n```\n\n#### canvas:node:set 两种模式（互斥）\n\n**模式 1 — 批量模式 `--data`**（多节点多参数）：\n```json\n[\n  {\n    \"id\": \"string\",       // [必填] 节点 ID\n    \"options\": {           // [必填] 要设置的参数对象\n      \"prompt\": \"赛博朋克\",\n      \"model\": \"kling-video-o1\"\n    }\n  }\n]\n```\n```bash\nzenvfx canvas:node:set --data [{\"id\":\"node1\",\"options\":{\"prompt\":\"赛博朋克\",\"model\":\"kling-video-o1\"}}] --canvas \"$CANVAS_PATH\"\n```\n\n**模式 2 — 快捷模式**（单节点单参数，LLM 友好，无需构造 JSON）：\n```bash\nzenvfx canvas:node:set --id node-abc --option prompt --value \"一只银渐层胖猫咪\" --canvas \"$CANVAS_PATH\"\n# JSON 值使用 --value-json\nzenvfx canvas:node:set --id node-abc --option config --value-json {\"width\":1024} --canvas \"$CANVAS_PATH\"\n```\n\n> ⚠️ `--data` 与 `--id + --option + --value` 互斥。传了 `--data` 则忽略快捷模式参数。\n\n#### canvas:node:move 两种模式（互斥）\n\n```bash\n# 批量\nzenvfx canvas:node:move --data [{\"nodeId\":\"n1\",\"position\":\"100,200\"},{\"nodeId\":\"n2\",\"position\":{\"x\":300,\"y\":400}}] --canvas \"$CANVAS_PATH\"\n\n# 快捷\nzenvfx canvas:node:move --id node-abc --position \"100,200\" --canvas \"$CANVAS_PATH\"\nzenvfx canvas:node:move --id node-abc --position {\"x\":100,\"y\":200} --canvas \"$CANVAS_PATH\"\n```\n\n> **节点位置**：添加多个节点时用 `position` 指定坐标，避免叠加。建议水平间隔 400px：`\"0,0\"`、`\"400,0\"`、`\"800,0\"`。\n\n### 打组操作 `[S]`\n\n> ⚠️ 同样**必须**携带 `--canvas <path>` 参数。所有写操作执行后**自动保存**。\n>\n> **打组必须一次做到完整收尾**：当用户要求\"打组/分组/整理成组\"时，优先只调用 `canvas:node:group`。该命令内部会自动完成：创建组 → 对新组/受影响父组执行组排序 → 检查顶层重叠 → 必要时整体平移避免重叠。不要在打组后停在\"已创建组\"，需根据返回的 `sortedGroups` / `overlapCheck` 确认布局已收尾；只有用户明确要求重新排序某个已有组时，才额外调用 `canvas:node:group:sort`。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:group --node-ids <id1,id2,...> [--name <name>] --canvas <path>` | 将一批节点打包为新组（自动剥离原父组成员、自动派生组的边/实体引用，并自动排序/检查重叠/必要时避让） |\n| `canvas:node:ungroup --group-id <id> --canvas <path>` | 解散组，成员上浮到父级 |\n| `canvas:node:group:info --group-id <id> --canvas <path>` | 查询组信息（id/name/members/color/bounds，**只读**） |\n| `canvas:node:group:members --group-id <id> --node-ids <id1,id2,...> --canvas <path>` | 全量替换组成员，自动重派生 edges/entities |\n| `canvas:node:group:color --group-id <id> --color <颜色> --canvas <path>` | 修改组颜色标签，可选值：`gray` / `red` / `orange` / `yellow` / `green` / `cyan` / `blue` / `purple` / `none`（清除颜色） |\n| `canvas:node:group:sort --group-id <id> --canvas <path>` | 对组内节点执行依赖流自动排序布局（基于内部边自动调整位置） |\n| `canvas:node:group:execute --group-id <id> --canvas <path>` | 按依赖顺序执行组内所有可执行节点（异步触发，进度通过 `task:status` 查询） |\n| `canvas:node:group:cancel --group-id <id> --canvas <path>` | 取消组的按序执行（停止组内所有进行中或 pending 的子节点） |\n\n**示例**：\n\n```bash\n# 1. 把 3 个节点打成一个组并命名（自动完成组排序 + 顶层重叠检查/避让）\nzenvfx canvas:node:group --node-ids n1,n2,n3 --name \"场景A\" --canvas \"$CANVAS_PATH\"\n# → { groupId: \"group_xxx\", status: \"ok\", sortedGroups: [...], overlapCheck: { checked, movedGroups, overlapsBefore, overlapsAfter } }\n\n# 2. 查询组详情\nzenvfx canvas:node:group:info --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 3. 改颜色 / 清除颜色\nzenvfx canvas:node:group:color --group-id group_xxx --color blue --canvas \"$CANVAS_PATH\"\nzenvfx canvas:node:group:color --group-id group_xxx --color none --canvas \"$CANVAS_PATH\"\n\n# 4. 改成员（全量替换）\nzenvfx canvas:node:group:members --group-id group_xxx --node-ids n1,n4 --canvas \"$CANVAS_PATH\"\n\n# 5. 组内自动排序\nzenvfx canvas:node:group:sort --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 6. 按依赖顺序执行组内节点（异步）\nzenvfx canvas:node:group:execute --group-id group_xxx --canvas \"$CANVAS_PATH\"\n# 查进度：zenvfx task:status --ids <taskIds> --canvas-id <canvasId>\n\n# 7. 取消执行\nzenvfx canvas:node:group:cancel --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 8. 解散\nzenvfx canvas:node:ungroup --group-id group_xxx --canvas \"$CANVAS_PATH\"\n```\n\n**参数校验错误提示（打组命令）**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `--node-ids` 为空 | `参数校验失败: --node-ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n| 任一 nodeId 不存在 | `Node not found: <id>` | `NODE_NOT_FOUND` |\n| `--group-id` 对应节点不是 group 类型 | `Node <id> is not a group` | `NODE_VALIDATION_FAILED` |\n| `groupNodes` 归一化后成员为空 | `No valid nodes to group` | `NODE_VALIDATION_FAILED` |\n| `--color` 取值非法 | 由 oclif options 拒绝并列出可选值 | — |\n\n> 💡 **打组语义提示**：\n> - `canvas:node:group` 的 `--node-ids` **可以混合普通节点和已有的组**。当传入的节点是另一个组的成员时，工具会自动从原父组中剥离，避免重复归属。\n> - `canvas:node:group` 默认会自动执行布局收尾：排序新组/受影响父组，并检查顶层重叠；若 `overlapCheck.overlapsAfter > 0`，需要继续使用 `canvas:node:move` 或再次组织布局，不能直接宣称布局完美。\n> - `canvas:node:group:members` 是**全量替换**而非增量；想加成员请先 `info` 查出当前 members，合并后再传入。\n> - `canvas:node:group:sort` 仅对组的**直接成员**做布局，不会递归子组内部；普通打组场景无需再额外调用，因为 `canvas:node:group` 已自动收尾。\n\n### 连线操作 `[S]`\n\n> ⚠️ 同样**必须**携带 `--canvas <path>` 参数。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list --canvas <path>` | 列出所有连线 |\n| `canvas:edge:add --data <JSON数组> --canvas <path>` | 批量连接节点 |\n| `canvas:edge:remove --ids <id1,id2> --canvas <path>` | 批量删除连线 |\n\n#### canvas:edge:add --data 格式\n\n```json\n[\n  {\n    \"source\": \"string\",        // [必填] 源节点 ID\n    \"sourceHandle\": \"string\",  // [必填] 源节点输出 handle（pinName）\n    \"target\": \"string\",        // [必填] 目标节点 ID\n    \"targetHandle\": \"string\"   // [必填] 目标节点输入 handle（pinName）\n  }\n]\n```\n\n**示例**：\n```bash\nzenvfx canvas:edge:add --data [{\"source\":\"n1\",\"sourceHandle\":\"output\",\"target\":\"n2\",\"targetHandle\":\"ref_images\"}] --canvas \"$CANVAS_PATH\"\n```\n\n**参数校验错误提示（连线命令）**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `edge:add` JSON 解析失败 | `--data JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `edge:add` 不是非空数组 | `--data 必须是非空 JSON 数组` | `INVALID_JSON` |\n| `edge:add` 缺少必填字段 | `参数校验失败: data[N].source 是必填项` 等 | `MISSING_VALUE` |\n| `edge:remove` --ids 为空 | `参数校验失败: --ids 至少需要包含一个边 ID` | `MISSING_VALUE` |\n\n### 任务查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `task:status --ids <taskId1,taskId2> --canvas-id <id>` | 批量查询任务状态（`--ids` 和 `--canvas-id` 均为必填） |\n\n**查询命令参数校验**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `node:model` 未提供 nodeType | `参数校验失败: nodeTypes 是必填项，请提供至少一个节点类型` | `MISSING_VALUE` |\n| `node:model` 未知类型 | `未知的节点类型: <xxx>`（返回 validTypes 列表，不中断） | — |\n| `task:status` --ids 为空 | `参数校验失败: --ids 至少需要包含一个任务 ID` | `MISSING_VALUE` |\n| `task:status` project 未配置 | `参数校验失败: project 未配置，请通过 auth:login 或 config:set defaultProject 设置` | `MISSING_CONFIG` |\n| `canvas:run` --ids 为空 | `参数校验失败: --ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`sourceHandle` 和 `targetHandle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:set`、`canvas:node:move`、`canvas:edge:add`、`canvas:edge:remove`、`canvas:node:group*` 系列执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n> 注：旧版的 `canvas:node:props` 已下线，统一通过 `canvas:node:set` 设置参数。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n### 4. canvas:open 一般无需手动调用\n\n所有 `[S]` 命令在执行时会**自动按 `--canvas` 路径打开/复用 Session**。只有在你需要显式预热 daemon、提前感知错误时才调用 `canvas:open`。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```\n0. auth:login <token>                                      （一次性）\n1. canvas:create --name \"xxx\"                              （自动使用 defaultWorkspace）\n2. canvas:node:add --data [{\"type\":\"normal_video_generator\",\"position\":\"0,0\",\"options\":{\"prompt\":\"...\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\"}}] --canvas \"${CANVAS_PATH}\"\n3. 选 A 或 B 运行：\n   A. 同步：canvas:run --ids $NODE_ID --wait --timeout 600 --canvas \"${CANVAS_PATH}\"\n      → 阻塞返回最终 outputs，最简单\n   B. 异步：canvas:run --ids $NODE_ID --canvas \"${CANVAS_PATH}\"\n      → 立即返回 query_hint，再用 task:status 轮询\n```\n\n### 同步 vs 异步选择\n\n| 场景 | 推荐 |\n|------|------|\n| 单节点 / 短链路 / 想\"一行命令拿结果\" | `canvas:run --wait --timeout 600` |\n| 多节点并发触发，调用方自己控制轮询节奏 | 默认异步 + `task:status` |\n| LLM Agent 想避免长时间阻塞主进程 | 默认异步，把 `query_hint` 保存到任务上下文 |\n| 在 shell 脚本里串联多个步骤 | `--wait` 更直观；超时按节点类型设置（图片 300s、视频 1800s） |\n\n### 异步轮询最佳实践\n\n异步模式 `canvas:run` 立即返回，结果中包含 `query_hint`：\n\n```json\n{\n  \"submitted\": true,\n  \"mode\": \"async\",\n  \"results\": [\n    { \"nodeId\": \"node1\", \"taskId\": \"abc1234\", \"status\": \"pending\" }\n  ],\n  \"query_hint\": {\n    \"command\": \"task:status --ids abc1234 --canvas-id xxx\",\n    \"instruction\": \"请使用上述命令批量查询任务结果，建议间隔 15s\"\n  }\n}\n```\n\n**轮询步骤**：\n\n1. `canvas:run --ids <nodeId1,nodeId2>` — 立即返回 `results` 和 `query_hint`\n2. 直接执行 `query_hint.command`（已自动拼接所有 taskId）\n3. 每 **15 秒**轮询一次 `task:status --ids <taskIds> --canvas-id <canvasId>`\n4. 当所有任务 `status` 为 `completed` / `failed` 时停止，最长 **30 分钟**\n\n> `outputs` 中有效 URL 在 `url` 字段（带 COS 签名），`download_url` 可能为空。\n\n### 完整示例（同步等待版）\n\n```bash\n# 0. 认证\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 批量添加节点（canvas:open 自动执行，无需手动调用）\nRESULT=$(zenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"name\":\"文生视频\",\"position\":\"0,0\",\"options\":{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}}] --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 3. 同步运行（阻塞等待最终结果）\nzenvfx canvas:run --ids $NODE_ID --wait --timeout 1200 --canvas \"${CANVAS_PATH}\"\n```\n\n### 完整示例（异步轮询版）\n\n```bash\n# 1~2 同上\n\n# 3. 异步运行\nRUN_RESULT=$(zenvfx canvas:run --ids $NODE_ID --canvas \"${CANVAS_PATH}\" 2>/dev/null)\n# 从 query_hint 获取轮询命令\nQUERY_CMD=$(echo $RUN_RESULT | grep -o '\"command\":\"[^\"]*\"' | head -1 | sed 's/\"command\":\"//;s/\"$//')\n\n# 4. 轮询任务状态（每 15s 一次）\nwhile true; do\n  STATUS=$(zenvfx $QUERY_CMD 2>/dev/null)\n  if echo \"$STATUS\" | grep -qE '\"status\":\"(completed|failed)\"'; then\n    echo \"$STATUS\"\n    break\n  fi\n  sleep 15\ndone\n```\n\n---\n\n## 节点参数\n\n> **重要**：model/clarity/ratio/duration 的值**必须通过 `node:model <nodeType>` 或 `node:defs` 动态查询**，不要硬编码。\n\n> **视频节点建议**：模型 `kling` + 分辨率 `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n> **node:model 支持批量查询**：`node:model normal_video_generator,image_generator` 一次返回多个类型的模型列表。\n\n> **node:defs 一站式知识**：`node:defs` 同时返回本地 schema（pin/option）+ 后端模型枚举/参数，AI Agent 启动期一次拉取即可，避免后续多次往返。\n\n通过 `--data` 批量模式或 `--option` + `--value` 快捷模式传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n**节点类型**（`type` 必须是下列英文 snake_case 枚举之一，写错会报 `NODE_TYPE_INVALID`）：\n\n| `type` | 说明 |\n|--------|------|\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点（⚠️ **文本节点是 `text_input`，不是 `text`**） |\n| `image_generator` | 文/图生图 |\n| `normal_video_generator` | 文/图生视频 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 |\n| `comprehensive_reference_generator` | 全能参考生视频 |\n| `llm` | 大模型文本节点 |\n| `group` | 组节点 |\n| `video_process` | 视频处理（变速/帧率转换/冻帧延长/裁切） |\n| `frame_extraction` | 视频截帧 |\n\n> 中文（\"提示词\"、\"文本\"）是节点 `label`，不是 `type`，传给 `canvas:node:add` 的 `--data` 中会直接失败。\n\n### Prompt 占位符\n\nPrompt 中可以用 `@` 前缀引用**上游节点通过连线传入的输入资源**。占位符直接写在 `canvas:node:set` 的 prompt 值中即可，画布引擎运行时会自动解析。\n\n**支持的占位符**（数字后缀可选，默认 1，如 `@提示词` 等价于 `@提示词1`）：\n\n| 占位符 | 含义 | 上游节点类型 |\n|--------|------|------------|\n| `@提示词1`、`@提示词2`… | 引用上游 **文本节点** 的文本内容 | `text_input` / `llm` |\n| `@参考图`、`@参考图1`… | 引用上游 **图片节点** 的图片 | `image_input` / `image_generator` |\n| `@首帧图1`、`@首帧图2`… | 引用首帧参考图 | `image_input` / `image_generator` |\n| `@尾帧图1`、`@尾帧图2`… | 引用尾帧参考图 | `image_input` / `image_generator` |\n| `@参考视频`、`@参考视频1`… | 引用上游 **视频节点** 的视频 | `video_input` / 视频生成节点 |\n| `@参考音频`、`@参考音频1`… | 引用上游 **音频节点** 的音频 | `audio_input` |\n\n**`@提示词` 引用上游文本节点**（最常用）：\n\n用 `text_input` 节点写好提示词文本，连线到生成节点的\"提示词\"输入口，然后在 prompt 中用 `@提示词1` 引用。画布引擎运行时会**直接替换为上游文本节点的文本内容**。\n\n```bash\n# text_input 节点（id=text-001）prompt 值为 \"傍晚海边小孩嬉戏\"\n# 连线：text-001 → video-001 的\"提示词1\"输入口\nzenvfx canvas:node:set --id video-001 --option prompt --value \"帮我生成一段视频：@提示词1\" --canvas \"$CANVAS_PATH\"\n```\n\n**图片/视频/音频占位符**：\n\n同样直接写在 prompt 中，画布引擎运行时会根据模型自动转换为对应格式。\n\n```bash\nzenvfx canvas:node:set --id $VIDEO_NODE_ID --option prompt --value \"小孩奔向海浪@首帧图1，夕阳洒在海面@尾帧图1\" --canvas \"$CANVAS_PATH\"\n```\n\n> 想看模型最终拿到的 prompt 字面值？先用 `canvas:node:prompt --id <id> --prompt \"<原文>\" [--model <id>]` 预览解析结果。\n\n---\n\n## 批量返回格式说明\n\n编辑类操作均返回 Partial Success 格式：\n\n```json\n{\n  \"results\": [\n    { \"status\": \"ok\", \"id\": \"xxx\", \"type\": \"image_generator\", \"name\": \"生图节点\", \"position\": { \"x\": 0, \"y\": 0 } },\n    { \"status\": \"error\", \"id\": null, \"type\": \"unknown_type\", \"error\": \"NODE_TYPE_INVALID\" }\n  ],\n  \"successCount\": 1,\n  \"failCount\": 1\n}\n```\n\n- 批量操作中某项失败**不影响**其余项\n- 每项通过 `status` 字段标注 `\"ok\"` / `\"error\"`\n- 顶层返回 `successCount` / `failCount` 汇总\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | `auth:verify <token>` 或重新 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败（server overload） | 系统已内置重试 3 次（间隔 1s/2s/3s），仍失败则手动重试 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `NODE_TYPE_INVALID` | 节点类型不合法 | 用 `text_input` / `image_input` / `video_input` / `audio_input` / `image_generator` / `normal_video_generator` / `first_to_last_video_generator` / `composite_video_generator` / `comprehensive_reference_generator` / `llm` / `group` / `video_process` / `frame_extraction`；中文标签不是 `type` |\n| `INVALID_JSON` | `--data` / `--value-json` JSON 解析失败 | 检查引号、逗号、括号等 JSON 格式 |\n| `MISSING_VALUE` | 必填字段缺失 | 查看报错信息中标注的缺失字段（如 `data[0].type 是必填项`） |\n| `MISSING_CONFIG` | 配置缺失（project 等） | 通过 `auth:login` 或 `config:set defaultProject` 设置 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --ids <id>` 查看可用选项 |\n| `EDGE_HANDLE_INVALID` | 连线 handle 不合法 | `canvas:node:info --ids <id>` 查看 inputPins/outputPins |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `DAEMON_START_FAILED` | daemon 启动失败 | 检查端口占用，清理后重试 |\n| `DAEMON_CONNECTION_FAILED` | daemon 连接失败 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数，重跑 `node:model <类型>` 对齐参数 |\n| `UPLOAD_TOKEN_FAILED` / `UPLOAD_FAILED` / `REGISTER_ASSET_FAILED` | `file:upload` 各阶段失败（已内置 3 次重试） | 查 `error.message` 与 details；多为网络/凭证问题，过段时间重试 |\n| `NETWORK_ERROR` | 网络错误 | 检查网络连接，确认 host 配置 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\n**调试运行节点的请求体**（对照网页协议时常用）：\n\ndaemon 会把每次提交后端的 `submitTask` 请求体写到 `~/.config/zenvfx/daemon.log`。可用脚本快速取最近一次：\n\n```bash\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh           # 最近 1 次\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh 3         # 最近 3 次\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh 1 image_generator-xxx   # 按关键词过滤\n```\n\nFile v1.0.18:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.18\",\n  \"publishedAt\": 1781591624446\n}\n\nFile v1.0.18:skill-card.md\n\n## Description: <br>\nZenVFX CLI helps agents create AI videos, manage ZenVFX canvases, nodes, files, and interact with the ZenVFX platform through CLI commands. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[lenzli](https://clawhub.ai/user/lenzli) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and creative operators use this skill to guide agents through ZenVFX CLI workflows for AI video creation, canvas editing, node and edge management, file operations, and task status checks. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Broad triggers and destructive file, node, edge, or canvas operations could cause accidental changes. <br>\nMitigation: Use this skill only for intentional ZenVFX work, verify the active project, workspace, and canvas before mutations, and require explicit confirmation before deleting files, directories, nodes, edges, or canvases. <br>\nRisk: The required ZENVFX_MCP_TOKEN may grant access to ZenVFX resources. <br>\nMitigation: Keep the token scoped and private, avoid exposing it in prompts or logs, and verify authentication with the intended account before running workspace-changing commands. <br>\nRisk: The skill depends on the @tencent/zenvfx-cli package from the Tencent npm registry. <br>\nMitigation: Install only when the Tencent registry and package are trusted for the target environment, and review generated shell commands before execution. <br>\n\n\n## Reference(s): <br>\n- [ZenVFX CLI ClawHub release](https://clawhub.ai/lenzli/zenvfx-cli) <br>\n- [Tencent npm registry for @tencent/zenvfx-cli](https://mirrors.tencent.com/npm/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown with inline shell commands and JSON examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Guidance expects stdout JSON from zenvfx commands and often uses environment variables such as ZENVFX_MCP_TOKEN.] <br>\n\n## Skill Version(s): <br>\n1.0.18 (source: server release evidence, created 2026-06-16) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.17: 3 files, 12856 bytes\n\nFiles: skill-card.md (2103b), SKILL.md (31659b), _meta.json (130b)\n\nFile v1.0.17:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n**架构原则（v3）**：\n- **万物皆批处理**：所有编辑操作均接收 JSON 数组 / 逗号分隔 ID 列表，无论操作 1 个还是 N 个对象，底层统一为批量调用。\n- **运行节点支持同步/异步双模式**：`canvas:run` 默认异步，加 `--wait` 进入同步模式（daemon 内部轮询直到所有节点 completed/failed 才返回）。\n- **Partial Success**：批量操作逐项执行，某项失败不影响其余，返回 `results` 数组逐项标注状态。\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n\n# 仅校验 token（不切换默认项目/workspace）\nzenvfx auth:verify <token>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）\n```\n\n`project:switch` 自动解析 workspace 的规则（仅依赖 `userId`，不依赖 `username`，因为 username 是用户可自定义的别名）：\n1. **精确匹配**：`/{projectId}/用户空间/` 下目录名以 `_{userId}` 结尾\n2. **模糊匹配**：目录名包含 `userId`\n3. 均未命中则清空 `defaultWorkspace`，需手动设置\n\n也可手动设置：\n```bash\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `auth:verify <token>` | 仅校验 token 合法性并写入 `mcpToken`，不切换项目/workspace |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n| `project:list` | 列出项目 |\n| `project:switch <projectId>` | 切换项目（自动更新 defaultProject + defaultWorkspace，workspace 匹配仅依赖 `userId`，不依赖 `username`），可选 `--no-workspace` |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:id-to-path --id <id>` | 内部 ID 转路径 |\n| `file:upload --local-file <本地路径> --project-id <id> [--file-path <ZenFS路径>] [--title <名称>]` | 上传本地文件到 COS 并注册素材；`--file-path` 可省略（仅上传不写 ZenFS） |\n\n### 画布管理\n\n标注 `[S]` 的命令**必须携带 `--canvas <path>` 参数**。系统会根据 `--canvas` 路径**自动执行 `canvas:open`**（如果尚未打开），无需手动调用。\n\n> ⚠️ **`--data` / `--value-json` 的 JSON 值直接裸写，不加单引号或双引号包裹**。\n> 命令解析器使用空格切分（`split(/\\s+/)`），不支持引号转义。\n> - ✅ `--data [{\"type\":\"image_generator\"}]`\n> - ❌ `--data '[{\"type\":\"image_generator\"}]'`（单引号成为 JSON 值的一部分 → `JSON 解析失败`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布（不递归），可选 `--list-path` |\n| `canvas:open --canvas <path>` `[S]` | 显式打开画布（一般无需手动调用，其他 `[S]` 命令会自动触发） |\n| `canvas:info --canvas <path>` `[S]` | 查看画布信息 |\n| `canvas:save --canvas <path>` `[S]` | 保存画布（编辑命令已自动保存，通常不需要） |\n| `canvas:run --ids <id1,id2,...> --canvas <path>` `[S]` | 批量运行节点；默认异步立即返回 `query_hint`，加 `--wait` 进入同步模式 |\n\n#### canvas:run 同步/异步模式\n\n| 模式 | 触发 | 返回时机 | 适用场景 |\n|------|------|----------|----------|\n| **异步**（默认） | `canvas:run --ids ...` | 立即返回，含 `submitted`/`results[].taskId`/`query_hint` | 长链路、并发多节点；调用方按 `query_hint.command` 自行轮询 |\n| **同步** | `canvas:run --ids ... --wait` | 在 daemon 内部轮询直到全部 `completed`/`failed` 才返回最终结果（含 `outputs[].url`） | 单节点或短链路调试；脚本希望一次拿到结果 |\n\n- `--timeout <秒>` 仅在 `--wait` 时生效，默认 **1800（30 分钟）**。\n- 异步 IPC 超时按 `节点数 × 15s + 60s` 自动放宽，最低 120s。\n- 同步模式返回结构：\n  ```json\n  {\n    \"submitted\": true,\n    \"mode\": \"sync\",\n    \"timedOut\": false,\n    \"elapsed\": 62025,\n    \"results\": [\n      { \"taskId\": \"...\", \"status\": \"completed\", \"nodes\": [{ \"nodeId\": \"...\", \"status\": \"completed\", \"outputs\": [...], \"textOutputs\": [] }] }\n    ]\n  }\n  ```\n\n```bash\n# 同步等待两个图片节点跑完\nzenvfx canvas:run --ids image_generator-aaa,image_generator-bbb --wait --timeout 600 --canvas \"$CANVAS_PATH\"\n\n# 异步触发，自己轮询\nRUN=$(zenvfx canvas:run --ids node1,node2 --canvas \"$CANVAS_PATH\" 2>/dev/null)\n# 取 query_hint.command 后定期 zenvfx task:status ...\n```\n\n### 节点操作 `[S]`\n\n编辑类命令执行后**自动保存**画布。\n\n> ⚠️ **`--canvas` 是必填参数**：所有标注 `[S]` 的命令都**必须**携带 `--canvas <path>` 参数指定画布路径（或通过环境变量 `ZENVFX_CANVAS` 提供）。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list --canvas <path>` | 列出所有节点 |\n| `canvas:node:info --ids <id1,id2> --canvas <path>` | 批量查看节点详情（pins、options、taskId/taskStatus） |\n| `canvas:node:add --data <JSON数组> --canvas <path>` | 批量添加节点 |\n| `canvas:node:remove --ids <id1,id2> --canvas <path>` | 批量删除节点 |\n| `canvas:node:set --data <JSON数组> --canvas <path>` | 批量设置节点参数 |\n| `canvas:node:set --id <id> --option <name> --value <val> --canvas <path>` | 快捷模式：单节点单参数设置 |\n| `canvas:node:move --data <JSON数组> --canvas <path>` | 批量移动节点位置 |\n| `canvas:node:move --id <id> --position <x,y> --canvas <path>` | 快捷模式：单节点移动 |\n| `canvas:node:prompt --id <id> --prompt <text> --canvas <path>` | 解析 prompt 中的 @占位符（如 `@首帧图1`），可选 `--model` |\n| `node:model <nodeTypes>` | 查询节点支持的模型与参数枚举（支持逗号分隔多个类型） |\n| `node:list` | 列出所有可用节点类型定义（本地，不需网络） |\n| `node:defs` | 一站式返回所有节点完整定义（本地 schema + 后端模型/参数），AI Agent 加载节点知识首选 |\n\n#### 参数校验错误提示（节点命令通用）\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `--data` JSON 解析失败 | `--data JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `--data` 不是非空数组 | `--data 必须是非空 JSON 数组` | `INVALID_JSON` |\n| `node:add` 缺少 type | `参数校验失败: data[N].type 是必填项` | `MISSING_VALUE` |\n| `node:set` 批量模式缺少 id | `参数校验失败: data[N].id 是必填项` | `MISSING_VALUE` |\n| `node:set` 批量模式 options 不是对象 | `参数校验失败: data[N].options 必须是对象` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少 --id | `参数校验失败: 必须提供 --data（批量模式）或 --id + --option + --value（快捷模式）` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少 --option | `参数校验失败: 快捷模式需要 --option 指定选项名称` | `MISSING_VALUE` |\n| `node:set` 快捷模式缺少值 | `参数校验失败: 快捷模式必须提供 --value 或 --value-json` | `MISSING_VALUE` |\n| `--value-json` JSON 解析失败 | `--value-json JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `node:info/remove` --ids 为空 | `参数校验失败: --ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n| `node:move` 批量缺少 nodeId/position | `参数校验失败: data[N].nodeId 是必填项` / `data[N].position 是必填项` | `MISSING_VALUE` |\n| `node:move` 快捷模式缺少 --id 或 --position | `参数校验失败: 快捷模式需要 --position 指定目标位置` | `MISSING_VALUE` |\n\n#### canvas:node:add --data 格式\n\n```json\n[\n  {\n    \"type\": \"string\",     // [必填] 节点类型，如 \"image_generator\", \"normal_video_generator\"\n    \"name\": \"string\",     // [选填] 节点名称\n    \"position\": \"string\", // [选填] 坐标位置，如 \"100,200\"，默认 \"0,0\"\n    \"options\": {}         // [选填] 节点配置参数（如 prompt, model, clarity, ratio, duration 等），\n                          //        创建后立即设置，无需再单独调用 canvas:node:set\n  }\n]\n```\n\n**示例**：\n```bash\n# 基础：只创建节点\nzenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"position\":\"0,0\"},{\"type\":\"image_input\",\"position\":\"400,0\",\"name\":\"首帧图\"}] --canvas \"$CANVAS_PATH\"\n\n# 带 options：创建并设置参数（省去 canvas:node:set）\nzenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"name\":\"文生视频\",\"position\":\"0,0\",\"options\":{\"prompt\":\"傍晚海边小孩嬉戏\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}}] --canvas \"$CANVAS_PATH\"\n```\n\n#### canvas:node:set 两种模式（互斥）\n\n**模式 1 — 批量模式 `--data`**（多节点多参数）：\n```json\n[\n  {\n    \"id\": \"string\",       // [必填] 节点 ID\n    \"options\": {           // [必填] 要设置的参数对象\n      \"prompt\": \"赛博朋克\",\n      \"model\": \"kling-video-o1\"\n    }\n  }\n]\n```\n```bash\nzenvfx canvas:node:set --data [{\"id\":\"node1\",\"options\":{\"prompt\":\"赛博朋克\",\"model\":\"kling-video-o1\"}}] --canvas \"$CANVAS_PATH\"\n```\n\n**模式 2 — 快捷模式**（单节点单参数，LLM 友好，无需构造 JSON）：\n```bash\nzenvfx canvas:node:set --id node-abc --option prompt --value \"一只银渐层胖猫咪\" --canvas \"$CANVAS_PATH\"\n# JSON 值使用 --value-json\nzenvfx canvas:node:set --id node-abc --option config --value-json {\"width\":1024} --canvas \"$CANVAS_PATH\"\n```\n\n> ⚠️ `--data` 与 `--id + --option + --value` 互斥。传了 `--data` 则忽略快捷模式参数。\n\n#### canvas:node:move 两种模式（互斥）\n\n```bash\n# 批量\nzenvfx canvas:node:move --data [{\"nodeId\":\"n1\",\"position\":\"100,200\"},{\"nodeId\":\"n2\",\"position\":{\"x\":300,\"y\":400}}] --canvas \"$CANVAS_PATH\"\n\n# 快捷\nzenvfx canvas:node:move --id node-abc --position \"100,200\" --canvas \"$CANVAS_PATH\"\nzenvfx canvas:node:move --id node-abc --position {\"x\":100,\"y\":200} --canvas \"$CANVAS_PATH\"\n```\n\n> **节点位置**：添加多个节点时用 `position` 指定坐标，避免叠加。建议水平间隔 400px：`\"0,0\"`、`\"400,0\"`、`\"800,0\"`。\n\n### 打组操作 `[S]`\n\n> ⚠️ 同样**必须**携带 `--canvas <path>` 参数。所有写操作执行后**自动保存**。\n>\n> **打组必须一次做到完整收尾**：当用户要求\"打组/分组/整理成组\"时，优先只调用 `canvas:node:group`。该命令内部会自动完成：创建组 → 对新组/受影响父组执行组排序 → 检查顶层重叠 → 必要时整体平移避免重叠。不要在打组后停在\"已创建组\"，需根据返回的 `sortedGroups` / `overlapCheck` 确认布局已收尾；只有用户明确要求重新排序某个已有组时，才额外调用 `canvas:node:group:sort`。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:group --node-ids <id1,id2,...> [--name <name>] --canvas <path>` | 将一批节点打包为新组（自动剥离原父组成员、自动派生组的边/实体引用，并自动排序/检查重叠/必要时避让） |\n| `canvas:node:ungroup --group-id <id> --canvas <path>` | 解散组，成员上浮到父级 |\n| `canvas:node:group:info --group-id <id> --canvas <path>` | 查询组信息（id/name/members/color/bounds，**只读**） |\n| `canvas:node:group:members --group-id <id> --node-ids <id1,id2,...> --canvas <path>` | 全量替换组成员，自动重派生 edges/entities |\n| `canvas:node:group:color --group-id <id> --color <颜色> --canvas <path>` | 修改组颜色标签，可选值：`gray` / `red` / `orange` / `yellow` / `green` / `cyan` / `blue` / `purple` / `none`（清除颜色） |\n| `canvas:node:group:sort --group-id <id> --canvas <path>` | 对组内节点执行依赖流自动排序布局（基于内部边自动调整位置） |\n| `canvas:node:group:execute --group-id <id> --canvas <path>` | 按依赖顺序执行组内所有可执行节点（异步触发，进度通过 `task:status` 查询） |\n| `canvas:node:group:cancel --group-id <id> --canvas <path>` | 取消组的按序执行（停止组内所有进行中或 pending 的子节点） |\n\n**示例**：\n\n```bash\n# 1. 把 3 个节点打成一个组并命名（自动完成组排序 + 顶层重叠检查/避让）\nzenvfx canvas:node:group --node-ids n1,n2,n3 --name \"场景A\" --canvas \"$CANVAS_PATH\"\n# → { groupId: \"group_xxx\", status: \"ok\", sortedGroups: [...], overlapCheck: { checked, movedGroups, overlapsBefore, overlapsAfter } }\n\n# 2. 查询组详情\nzenvfx canvas:node:group:info --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 3. 改颜色 / 清除颜色\nzenvfx canvas:node:group:color --group-id group_xxx --color blue --canvas \"$CANVAS_PATH\"\nzenvfx canvas:node:group:color --group-id group_xxx --color none --canvas \"$CANVAS_PATH\"\n\n# 4. 改成员（全量替换）\nzenvfx canvas:node:group:members --group-id group_xxx --node-ids n1,n4 --canvas \"$CANVAS_PATH\"\n\n# 5. 组内自动排序\nzenvfx canvas:node:group:sort --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 6. 按依赖顺序执行组内节点（异步）\nzenvfx canvas:node:group:execute --group-id group_xxx --canvas \"$CANVAS_PATH\"\n# 查进度：zenvfx task:status --ids <taskIds> --canvas-id <canvasId>\n\n# 7. 取消执行\nzenvfx canvas:node:group:cancel --group-id group_xxx --canvas \"$CANVAS_PATH\"\n\n# 8. 解散\nzenvfx canvas:node:ungroup --group-id group_xxx --canvas \"$CANVAS_PATH\"\n```\n\n**参数校验错误提示（打组命令）**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `--node-ids` 为空 | `参数校验失败: --node-ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n| 任一 nodeId 不存在 | `Node not found: <id>` | `NODE_NOT_FOUND` |\n| `--group-id` 对应节点不是 group 类型 | `Node <id> is not a group` | `NODE_VALIDATION_FAILED` |\n| `groupNodes` 归一化后成员为空 | `No valid nodes to group` | `NODE_VALIDATION_FAILED` |\n| `--color` 取值非法 | 由 oclif options 拒绝并列出可选值 | — |\n\n> 💡 **打组语义提示**：\n> - `canvas:node:group` 的 `--node-ids` **可以混合普通节点和已有的组**。当传入的节点是另一个组的成员时，工具会自动从原父组中剥离，避免重复归属。\n> - `canvas:node:group` 默认会自动执行布局收尾：排序新组/受影响父组，并检查顶层重叠；若 `overlapCheck.overlapsAfter > 0`，需要继续使用 `canvas:node:move` 或再次组织布局，不能直接宣称布局完美。\n> - `canvas:node:group:members` 是**全量替换**而非增量；想加成员请先 `info` 查出当前 members，合并后再传入。\n> - `canvas:node:group:sort` 仅对组的**直接成员**做布局，不会递归子组内部；普通打组场景无需再额外调用，因为 `canvas:node:group` 已自动收尾。\n\n### 连线操作 `[S]`\n\n> ⚠️ 同样**必须**携带 `--canvas <path>` 参数。\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list --canvas <path>` | 列出所有连线 |\n| `canvas:edge:add --data <JSON数组> --canvas <path>` | 批量连接节点 |\n| `canvas:edge:remove --ids <id1,id2> --canvas <path>` | 批量删除连线 |\n\n#### canvas:edge:add --data 格式\n\n```json\n[\n  {\n    \"source\": \"string\",        // [必填] 源节点 ID\n    \"sourceHandle\": \"string\",  // [必填] 源节点输出 handle（pinName）\n    \"target\": \"string\",        // [必填] 目标节点 ID\n    \"targetHandle\": \"string\"   // [必填] 目标节点输入 handle（pinName）\n  }\n]\n```\n\n**示例**：\n```bash\nzenvfx canvas:edge:add --data [{\"source\":\"n1\",\"sourceHandle\":\"output\",\"target\":\"n2\",\"targetHandle\":\"ref_images\"}] --canvas \"$CANVAS_PATH\"\n```\n\n**参数校验错误提示（连线命令）**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `edge:add` JSON 解析失败 | `--data JSON 解析失败，请检查格式: <原始输入>` | `INVALID_JSON` |\n| `edge:add` 不是非空数组 | `--data 必须是非空 JSON 数组` | `INVALID_JSON` |\n| `edge:add` 缺少必填字段 | `参数校验失败: data[N].source 是必填项` 等 | `MISSING_VALUE` |\n| `edge:remove` --ids 为空 | `参数校验失败: --ids 至少需要包含一个边 ID` | `MISSING_VALUE` |\n\n### 任务查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `task:status --ids <taskId1,taskId2> --canvas-id <id>` | 批量查询任务状态（`--ids` 和 `--canvas-id` 均为必填） |\n\n**查询命令参数校验**：\n\n| 场景 | 错误信息 | 错误码 |\n|------|----------|--------|\n| `node:model` 未提供 nodeType | `参数校验失败: nodeTypes 是必填项，请提供至少一个节点类型` | `MISSING_VALUE` |\n| `node:model` 未知类型 | `未知的节点类型: <xxx>`（返回 validTypes 列表，不中断） | — |\n| `task:status` --ids 为空 | `参数校验失败: --ids 至少需要包含一个任务 ID` | `MISSING_VALUE` |\n| `task:status` project 未配置 | `参数校验失败: project 未配置，请通过 auth:login 或 config:set defaultProject 设置` | `MISSING_CONFIG` |\n| `canvas:run` --ids 为空 | `参数校验失败: --ids 至少需要包含一个节点 ID` | `MISSING_VALUE` |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`sourceHandle` 和 `targetHandle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:set`、`canvas:node:move`、`canvas:edge:add`、`canvas:edge:remove`、`canvas:node:group*` 系列执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n> 注：旧版的 `canvas:node:props` 已下线，统一通过 `canvas:node:set` 设置参数。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n### 4. canvas:open 一般无需手动调用\n\n所有 `[S]` 命令在执行时会**自动按 `--canvas` 路径打开/复用 Session**。只有在你需要显式预热 daemon、提前感知错误时才调用 `canvas:open`。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```\n0. auth:login <token>                                      （一次性）\n1. canvas:create --name \"xxx\"                              （自动使用 defaultWorkspace）\n2. canvas:node:add --data [{\"type\":\"normal_video_generator\",\"position\":\"0,0\",\"options\":{\"prompt\":\"...\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\"}}] --canvas \"${CANVAS_PATH}\"\n3. 选 A 或 B 运行：\n   A. 同步：canvas:run --ids $NODE_ID --wait --timeout 600 --canvas \"${CANVAS_PATH}\"\n      → 阻塞返回最终 outputs，最简单\n   B. 异步：canvas:run --ids $NODE_ID --canvas \"${CANVAS_PATH}\"\n      → 立即返回 query_hint，再用 task:status 轮询\n```\n\n### 同步 vs 异步选择\n\n| 场景 | 推荐 |\n|------|------|\n| 单节点 / 短链路 / 想\"一行命令拿结果\" | `canvas:run --wait --timeout 600` |\n| 多节点并发触发，调用方自己控制轮询节奏 | 默认异步 + `task:status` |\n| LLM Agent 想避免长时间阻塞主进程 | 默认异步，把 `query_hint` 保存到任务上下文 |\n| 在 shell 脚本里串联多个步骤 | `--wait` 更直观；超时按节点类型设置（图片 300s、视频 1800s） |\n\n### 异步轮询最佳实践\n\n异步模式 `canvas:run` 立即返回，结果中包含 `query_hint`：\n\n```json\n{\n  \"submitted\": true,\n  \"mode\": \"async\",\n  \"results\": [\n    { \"nodeId\": \"node1\", \"taskId\": \"abc1234\", \"status\": \"pending\" }\n  ],\n  \"query_hint\": {\n    \"command\": \"task:status --ids abc1234 --canvas-id xxx\",\n    \"instruction\": \"请使用上述命令批量查询任务结果，建议间隔 15s\"\n  }\n}\n```\n\n**轮询步骤**：\n\n1. `canvas:run --ids <nodeId1,nodeId2>` — 立即返回 `results` 和 `query_hint`\n2. 直接执行 `query_hint.command`（已自动拼接所有 taskId）\n3. 每 **15 秒**轮询一次 `task:status --ids <taskIds> --canvas-id <canvasId>`\n4. 当所有任务 `status` 为 `completed` / `failed` 时停止，最长 **30 分钟**\n\n> `outputs` 中有效 URL 在 `url` 字段（带 COS 签名），`download_url` 可能为空。\n\n### 完整示例（同步等待版）\n\n```bash\n# 0. 认证\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 批量添加节点（canvas:open 自动执行，无需手动调用）\nRESULT=$(zenvfx canvas:node:add --data [{\"type\":\"normal_video_generator\",\"name\":\"文生视频\",\"position\":\"0,0\",\"options\":{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}}] --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 3. 同步运行（阻塞等待最终结果）\nzenvfx canvas:run --ids $NODE_ID --wait --timeout 1200 --canvas \"${CANVAS_PATH}\"\n```\n\n### 完整示例（异步轮询版）\n\n```bash\n# 1~2 同上\n\n# 3. 异步运行\nRUN_RESULT=$(zenvfx canvas:run --ids $NODE_ID --canvas \"${CANVAS_PATH}\" 2>/dev/null)\n# 从 query_hint 获取轮询命令\nQUERY_CMD=$(echo $RUN_RESULT | grep -o '\"command\":\"[^\"]*\"' | head -1 | sed 's/\"command\":\"//;s/\"$//')\n\n# 4. 轮询任务状态（每 15s 一次）\nwhile true; do\n  STATUS=$(zenvfx $QUERY_CMD 2>/dev/null)\n  if echo \"$STATUS\" | grep -qE '\"status\":\"(completed|failed)\"'; then\n    echo \"$STATUS\"\n    break\n  fi\n  sleep 15\ndone\n```\n\n---\n\n## 节点参数\n\n> **重要**：model/clarity/ratio/duration 的值**必须通过 `node:model <nodeType>` 或 `node:defs` 动态查询**，不要硬编码。\n\n> **视频节点建议**：模型 `kling` + 分辨率 `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n> **node:model 支持批量查询**：`node:model normal_video_generator,image_generator` 一次返回多个类型的模型列表。\n\n> **node:defs 一站式知识**：`node:defs` 同时返回本地 schema（pin/option）+ 后端模型枚举/参数，AI Agent 启动期一次拉取即可，避免后续多次往返。\n\n通过 `--data` 批量模式或 `--option` + `--value` 快捷模式传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n**节点类型**（`type` 必须是下列英文 snake_case 枚举之一，写错会报 `NODE_TYPE_INVALID`）：\n\n| `type` | 说明 |\n|--------|------|\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点（⚠️ **文本节点是 `text_input`，不是 `text`**） |\n| `image_generator` | 文/图生图 |\n| `normal_video_generator` | 文/图生视频 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 |\n| `comprehensive_reference_generator` | 全能参考生视频 |\n| `llm` | 大模型文本节点 |\n| `group` | 组节点 |\n| `video_process` | 视频处理（变速/帧率转换/冻帧延长/裁切） |\n| `frame_extraction` | 视频截帧 |\n\n> 中文（\"提示词\"、\"文本\"）是节点 `label`，不是 `type`，传给 `canvas:node:add` 的 `--data` 中会直接失败。\n\n### Prompt 占位符\n\nPrompt 中可以用 `@` 前缀引用**上游节点通过连线传入的输入资源**。占位符直接写在 `canvas:node:set` 的 prompt 值中即可，画布引擎运行时会自动解析。\n\n**支持的占位符**（数字后缀可选，默认 1，如 `@提示词` 等价于 `@提示词1`）：\n\n| 占位符 | 含义 | 上游节点类型 |\n|--------|------|------------|\n| `@提示词1`、`@提示词2`… | 引用上游 **文本节点** 的文本内容 | `text_input` / `llm` |\n| `@参考图`、`@参考图1`… | 引用上游 **图片节点** 的图片 | `image_input` / `image_generator` |\n| `@首帧图1`、`@首帧图2`… | 引用首帧参考图 | `image_input` / `image_generator` |\n| `@尾帧图1`、`@尾帧图2`… | 引用尾帧参考图 | `image_input` / `image_generator` |\n| `@参考视频`、`@参考视频1`… | 引用上游 **视频节点** 的视频 | `video_input` / 视频生成节点 |\n| `@参考音频`、`@参考音频1`… | 引用上游 **音频节点** 的音频 | `audio_input` |\n\n**`@提示词` 引用上游文本节点**（最常用）：\n\n用 `text_input` 节点写好提示词文本，连线到生成节点的\"提示词\"输入口，然后在 prompt 中用 `@提示词1` 引用。画布引擎运行时会**直接替换为上游文本节点的文本内容**。\n\n```bash\n# text_input 节点（id=text-001）prompt 值为 \"傍晚海边小孩嬉戏\"\n# 连线：text-001 → video-001 的\"提示词1\"输入口\nzenvfx canvas:node:set --id video-001 --option prompt --value \"帮我生成一段视频：@提示词1\" --canvas \"$CANVAS_PATH\"\n```\n\n**图片/视频/音频占位符**：\n\n同样直接写在 prompt 中，画布引擎运行时会根据模型自动转换为对应格式。\n\n```bash\nzenvfx canvas:node:set --id $VIDEO_NODE_ID --option prompt --value \"小孩奔向海浪@首帧图1，夕阳洒在海面@尾帧图1\" --canvas \"$CANVAS_PATH\"\n```\n\n> 想看模型最终拿到的 prompt 字面值？先用 `canvas:node:prompt --id <id> --prompt \"<原文>\" [--model <id>]` 预览解析结果。\n\n---\n\n## 批量返回格式说明\n\n编辑类操作均返回 Partial Success 格式：\n\n```json\n{\n  \"results\": [\n    { \"status\": \"ok\", \"id\": \"xxx\", \"type\": \"image_generator\", \"name\": \"生图节点\", \"position\": { \"x\": 0, \"y\": 0 } },\n    { \"status\": \"error\", \"id\": null, \"type\": \"unknown_type\", \"error\": \"NODE_TYPE_INVALID\" }\n  ],\n  \"successCount\": 1,\n  \"failCount\": 1\n}\n```\n\n- 批量操作中某项失败**不影响**其余项\n- 每项通过 `status` 字段标注 `\"ok\"` / `\"error\"`\n- 顶层返回 `successCount` / `failCount` 汇总\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | `auth:verify <token>` 或重新 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败（server overload） | 系统已内置重试 3 次（间隔 1s/2s/3s），仍失败则手动重试 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `NODE_TYPE_INVALID` | 节点类型不合法 | 用 `text_input` / `image_input` / `video_input` / `audio_input` / `image_generator` / `normal_video_generator` / `first_to_last_video_generator` / `composite_video_generator` / `comprehensive_reference_generator` / `llm` / `group` / `video_process` / `frame_extraction`；中文标签不是 `type` |\n| `INVALID_JSON` | `--data` / `--value-json` JSON 解析失败 | 检查引号、逗号、括号等 JSON 格式 |\n| `MISSING_VALUE` | 必填字段缺失 | 查看报错信息中标注的缺失字段（如 `data[0].type 是必填项`） |\n| `MISSING_CONFIG` | 配置缺失（project 等） | 通过 `auth:login` 或 `config:set defaultProject` 设置 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --ids <id>` 查看可用选项 |\n| `EDGE_HANDLE_INVALID` | 连线 handle 不合法 | `canvas:node:info --ids <id>` 查看 inputPins/outputPins |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `DAEMON_START_FAILED` | daemon 启动失败 | 检查端口占用，清理后重试 |\n| `DAEMON_CONNECTION_FAILED` | daemon 连接失败 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数，重跑 `node:model <类型>` 对齐参数 |\n| `UPLOAD_TOKEN_FAILED` / `UPLOAD_FAILED` / `REGISTER_ASSET_FAILED` | `file:upload` 各阶段失败（已内置 3 次重试） | 查 `error.message` 与 details；多为网络/凭证问题，过段时间重试 |\n| `NETWORK_ERROR` | 网络错误 | 检查网络连接，确认 host 配置 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\n**调试运行节点的请求体**（对照网页协议时常用）：\n\ndaemon 会把每次提交后端的 `submitTask` 请求体写到 `~/.config/zenvfx/daemon.log`。可用脚本快速取最近一次：\n\n```bash\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh           # 最近 1 次\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh 3         # 最近 3 次\nbash src/libs/zenvfx-cli/test/scenarios/dump-last-submit.sh 1 image_generator-xxx   # 按关键词过滤\n```\n\nFile v1.0.17:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.17\",\n  \"publishedAt\": 1781591157683\n}\n\nFile v1.0.17:skill-card.md\n\n## Description: <br>\nUse this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[lenzli](https://clawhub.ai/user/lenzli) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and creators use this skill to operate the ZenVFX CLI for AI video workflows, including project setup, canvas and node editing, file upload, task execution, and status checks. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill requires a ZenVFX token and uses an external CLI package installed from the Tencent npm mirror. <br>\nMitigation: Install only after confirming trust in @tencent/zenvfx-cli and the Tencent npm mirror, and handle ZENVFX_MCP_TOKEN as a secret. <br>\nRisk: The documented CLI workflow can modify ZenVFX project content, including deleting files, uploading local files, switching projects or workspaces, and running generation jobs. <br>\nMitigation: Review proposed commands, project and workspace targets, file paths, canvas paths, and node IDs before execution, especially for destructive or account-changing operations. <br>\n\n\n## Reference(s): <br>\n- [ClawHub ZenVFX CLI release](https://clawhub.ai/lenzli/zenvfx-cli) <br>\n- [Tencent npm mirror](https://mirrors.tencent.com/npm/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Shell commands, Configuration, Guidance] <br>\n**Output Format:** [Markdown with inline shell commands and JSON examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Guidance expects the zenvfx CLI, a ZenVFX token, and JSON command output.] <br>\n\n## Skill Version(s): <br>\n1.0.17 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.16: 3 files, 6476 bytes\n\nFiles: skill-card.md (2069b), SKILL.md (11584b), _meta.json (130b)\n\nFile v1.0.16:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）\n```\n\n`project:switch` 自动解析 workspace 的规则（仅依赖 `userId`，不依赖 `username`，因为 username 是用户可自定义的别名）：\n1. **精确匹配**：`/{projectId}/用户空间/` 下目录名以 `_{userId}` 结尾\n2. **模糊匹配**：目录名包含 `userId`\n3. 均未命中则清空 `defaultWorkspace`，需手动设置\n\n也可手动设置：\n```bash\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n| `project:list` | 列出项目 |\n| `project:switch <projectId>` | 切换项目（自动更新 defaultProject + defaultWorkspace，workspace 匹配仅依赖 `userId`，不依赖 `username`），可选 `--no-workspace` |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:upload --local-file <本地路径> --file-path <ZenFS路径> --project-id <id>` | 上传本地文件到 COS 并注册到 ZenFS，可选 `--title` |\n\n### 画布管理（标 `[S]` 的命令需先 `canvas:open`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布，可选 `--list-path` |\n| `canvas:open --canvas <path>` | 打开画布（启动 Session） |\n| `canvas:info` `[S]` | 查看画布信息 |\n| `canvas:save` `[S]` | 手动保存（一般不需要，见下方说明） |\n| `canvas:run --node <id>` `[S]` | 运行节点，`--wait` 同步等待（默认超时 10 分钟） |\n\n### 节点操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list` | 列出所有节点 |\n| `canvas:node:info --id <id>` | 节点详情（options/values 已 resolve 实际值，含 taskId/taskStatus） |\n| `canvas:node:add <type>` | 添加节点，可选 `--name --position \"x,y\"` |\n| `canvas:node:remove --id <id>` | 删除节点 |\n| `canvas:node:props --id <id>` | 修改节点自身属性，可选 `--name`（标题）`--position \"x,y\"`（位置） |\n| `canvas:node:set --id <id>` | 设置参数（推荐 `--options-json`） |\n| `canvas:node:prompt --id <id> --prompt <text>` | 解析 prompt 中 @占位符，可选 `--model` |\n\n多节点时用 `--position \"x,y\"` 避免重叠，建议水平间隔 400px。\n\n### 连线操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list` | 列出所有连线 |\n| `canvas:edge:add` | 连线（`--source --source-handle --target --target-handle`） |\n| `canvas:edge:remove --id <id>` | 删除连线 |\n\n### 查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `node:list` | 所有可用节点类型定义（本地） |\n| `node:defs` | 完整节点定义含模型信息（需认证） |\n| `node:model <nodeType>` | 节点支持的模型列表（需认证） |\n| `task:status <taskId> --canvas-id <id>` | 查询任务状态 |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`--source-handle` 和 `--target-handle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:props`、`canvas:node:set`、`canvas:edge:add`、`canvas:edge:remove` 执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```bash\n# 0. 认证（一次性）\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 打开画布\nzenvfx canvas:open --canvas \"${CANVAS_PATH}.canvas\"\n\n# 3. 添加节点\nRESULT=$(zenvfx canvas:node:add normal_video_generator --name \"文生视频\" --position \"0,0\" --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 4. 设置参数（model/clarity 等值须通过 node:model <type> 动态查询，勿硬编码）\nzenvfx canvas:node:set --id $NODE_ID --options-json \\\n  '{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}' \\\n  --canvas \"${CANVAS_PATH}\"\n\n# 5. 运行并等待（推荐 --wait，超时 30 分钟）\nzenvfx canvas:run --node $NODE_ID --canvas \"${CANVAS_PATH}\" --wait --timeout 1800000 2>/dev/null\n# 返回: {\"status\":\"completed\",\"outputs\":[{\"url\":\"...\"}]}\n```\n\n**异步模式**：不加 `--wait` 立即返回 `taskId`，再用 `task:status <taskId> --canvas-id <canvasId>` 轮询（建议 10 秒间隔，30 分钟超时）。`canvasId` 通过 `file:path-to-id --path \"${CANVAS_PATH}.canvas\"` 获取。\n\n---\n\n## 节点信息返回结构\n\n`canvas:node:info --id <id>` 返回的 `options` 和 `values` 数组中，每个条目已 resolve 为：\n\n| 字段 | 说明 |\n|------|------|\n| `optionName` | 参数名 |\n| `refId` | entity 引用 ID |\n| `value` | **当前实际值**（set 后可直接通过 info 读回） |\n| `type` | 值类型（`text`/`string`/`number`/`unknown`） |\n\n示例：\n```json\n{\n  \"options\": [\n    {\"optionName\": \"prompt\", \"value\": \"一只猫咪\", \"type\": \"text\"},\n    {\"optionName\": \"model\", \"value\": \"kling\", \"type\": \"string\"},\n    {\"optionName\": \"ratio\", \"value\": \"16:9\", \"type\": \"string\"}\n  ]\n}\n```\n\n---\n\n## 节点参数\n\n通过 `--options-json` 统一传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n常用节点类型：\n\n| nodeUiType | 说明 |\n|---|---|\n| `normal_video_generator` | 文生视频 / 图生视频 / 图片参考 |\n| `image_generator` | 文生图 / 图生图 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 / 视频参考 / 动作迁移 |\n| `comprehensive_reference_generator` | 全能参考生视频（支持图/视频/音频混合输入） |\n| `llm` | 大模型节点（多模态理解，支持 Claude / Gemini / GPT） |\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点 |\n| `scene_rerender_*` | 场景转绘（首帧/尾帧/首尾帧，自定义节点） |\n| `video_relighting_*` | 视频重打光（自定义节点） |\n| `character_edit_*` | 角色编辑（人偶化/改变ID/保留ID，自定义节点） |\n| `creature_*` | 生物控制（表情/运动，自定义节点） |\n\n**视频节点建议**：模型 `kling` + `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n### Prompt @占位符\n\nprompt 中可用 `@参考图`、`@首帧图1`、`@尾帧图1`、`@参考视频`、`@参考音频` 引用上游输入。通过 `canvas:node:prompt` 命令自动转换为模型特定格式：\n\n| 模型 | `@首帧图1` → | `@尾帧图1` → | `@参考图` → |\n|------|-------------|-------------|------------|\n| `kling-video-o1` | `<<<image_1>>>` | `<<<image_2>>>` | `<<<image_1>>>` |\n| `viduq2-pro` | `@1` | `@2` | `@1` |\n| 其他 | `第一张首帧图` | `第一张尾帧图` | `第一张参考图` |\n\n用法：先调用 `canvas:node:prompt` 获取 `resolved` 字段，再写入节点。需连线已建立且上游已完成。\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | 重新获取后 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败 | 重试 2-3 次，间隔 3-5 秒 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --id <id>` 查看 |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\nFile v1.0.16:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.16\",\n  \"publishedAt\": 1777343699432\n}\n\nFile v1.0.16:skill-card.md\n\n## Description: <br>\nZenVFX CLI helps agents create AI videos and manage ZenVFX canvases, nodes, files, and tasks through the zenvfx command-line tool. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[lenzli](https://clawhub.ai/user/lenzli) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and creators use this skill to have an agent configure ZenVFX authentication, create and open canvases, add and connect generation nodes, run video or image generation tasks, and manage project files. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can use a saved token to change, upload, run, or delete assets in a ZenVFX workspace. <br>\nMitigation: Use a revocable token, avoid shared machines, and confirm the exact project, workspace, canvas, node ID, and file path before uploads, task runs, node removals, or file deletions. <br>\nRisk: ZenVFX CLI commands can start generation tasks or modify canvases once authenticated. <br>\nMitigation: Review proposed commands and parameters before execution, especially prompts, model choices, durations, paths, and destructive file or node operations. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/lenzli/zenvfx-cli) <br>\n- [Tencent npm registry](https://mirrors.tencent.com/npm/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Guidance, Shell commands, Configuration] <br>\n**Output Format:** [Markdown with inline shell commands and JSON command examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Commands target the zenvfx CLI and may read or modify the user's ZenVFX workspace.] <br>\n\n## Skill Version(s): <br>\n1.0.16 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.15: 2 files, 5343 bytes\n\nFiles: SKILL.md (11584b), _meta.json (130b)\n\nFile v1.0.15:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）\n```\n\n`project:switch` 自动解析 workspace 的规则（仅依赖 `userId`，不依赖 `username`，因为 username 是用户可自定义的别名）：\n1. **精确匹配**：`/{projectId}/用户空间/` 下目录名以 `_{userId}` 结尾\n2. **模糊匹配**：目录名包含 `userId`\n3. 均未命中则清空 `defaultWorkspace`，需手动设置\n\n也可手动设置：\n```bash\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n| `project:list` | 列出项目 |\n| `project:switch <projectId>` | 切换项目（自动更新 defaultProject + defaultWorkspace，workspace 匹配仅依赖 `userId`，不依赖 `username`），可选 `--no-workspace` |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:upload --local-file <本地路径> --file-path <ZenFS路径> --project-id <id>` | 上传本地文件到 COS 并注册到 ZenFS，可选 `--title` |\n\n### 画布管理（标 `[S]` 的命令需先 `canvas:open`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布，可选 `--list-path` |\n| `canvas:open --canvas <path>` | 打开画布（启动 Session） |\n| `canvas:info` `[S]` | 查看画布信息 |\n| `canvas:save` `[S]` | 手动保存（一般不需要，见下方说明） |\n| `canvas:run --node <id>` `[S]` | 运行节点，`--wait` 同步等待（默认超时 10 分钟） |\n\n### 节点操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list` | 列出所有节点 |\n| `canvas:node:info --id <id>` | 节点详情（options/values 已 resolve 实际值，含 taskId/taskStatus） |\n| `canvas:node:add <type>` | 添加节点，可选 `--name --position \"x,y\"` |\n| `canvas:node:remove --id <id>` | 删除节点 |\n| `canvas:node:props --id <id>` | 修改节点自身属性，可选 `--name`（标题）`--position \"x,y\"`（位置） |\n| `canvas:node:set --id <id>` | 设置参数（推荐 `--options-json`） |\n| `canvas:node:prompt --id <id> --prompt <text>` | 解析 prompt 中 @占位符，可选 `--model` |\n\n多节点时用 `--position \"x,y\"` 避免重叠，建议水平间隔 400px。\n\n### 连线操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list` | 列出所有连线 |\n| `canvas:edge:add` | 连线（`--source --source-handle --target --target-handle`） |\n| `canvas:edge:remove --id <id>` | 删除连线 |\n\n### 查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `node:list` | 所有可用节点类型定义（本地） |\n| `node:defs` | 完整节点定义含模型信息（需认证） |\n| `node:model <nodeType>` | 节点支持的模型列表（需认证） |\n| `task:status <taskId> --canvas-id <id>` | 查询任务状态 |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`--source-handle` 和 `--target-handle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:props`、`canvas:node:set`、`canvas:edge:add`、`canvas:edge:remove` 执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```bash\n# 0. 认证（一次性）\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 打开画布\nzenvfx canvas:open --canvas \"${CANVAS_PATH}.canvas\"\n\n# 3. 添加节点\nRESULT=$(zenvfx canvas:node:add normal_video_generator --name \"文生视频\" --position \"0,0\" --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 4. 设置参数（model/clarity 等值须通过 node:model <type> 动态查询，勿硬编码）\nzenvfx canvas:node:set --id $NODE_ID --options-json \\\n  '{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}' \\\n  --canvas \"${CANVAS_PATH}\"\n\n# 5. 运行并等待（推荐 --wait，超时 30 分钟）\nzenvfx canvas:run --node $NODE_ID --canvas \"${CANVAS_PATH}\" --wait --timeout 1800000 2>/dev/null\n# 返回: {\"status\":\"completed\",\"outputs\":[{\"url\":\"...\"}]}\n```\n\n**异步模式**：不加 `--wait` 立即返回 `taskId`，再用 `task:status <taskId> --canvas-id <canvasId>` 轮询（建议 10 秒间隔，30 分钟超时）。`canvasId` 通过 `file:path-to-id --path \"${CANVAS_PATH}.canvas\"` 获取。\n\n---\n\n## 节点信息返回结构\n\n`canvas:node:info --id <id>` 返回的 `options` 和 `values` 数组中，每个条目已 resolve 为：\n\n| 字段 | 说明 |\n|------|------|\n| `optionName` | 参数名 |\n| `refId` | entity 引用 ID |\n| `value` | **当前实际值**（set 后可直接通过 info 读回） |\n| `type` | 值类型（`text`/`string`/`number`/`unknown`） |\n\n示例：\n```json\n{\n  \"options\": [\n    {\"optionName\": \"prompt\", \"value\": \"一只猫咪\", \"type\": \"text\"},\n    {\"optionName\": \"model\", \"value\": \"kling\", \"type\": \"string\"},\n    {\"optionName\": \"ratio\", \"value\": \"16:9\", \"type\": \"string\"}\n  ]\n}\n```\n\n---\n\n## 节点参数\n\n通过 `--options-json` 统一传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n常用节点类型：\n\n| nodeUiType | 说明 |\n|---|---|\n| `normal_video_generator` | 文生视频 / 图生视频 / 图片参考 |\n| `image_generator` | 文生图 / 图生图 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 / 视频参考 / 动作迁移 |\n| `comprehensive_reference_generator` | 全能参考生视频（支持图/视频/音频混合输入） |\n| `llm` | 大模型节点（多模态理解，支持 Claude / Gemini / GPT） |\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点 |\n| `scene_rerender_*` | 场景转绘（首帧/尾帧/首尾帧，自定义节点） |\n| `video_relighting_*` | 视频重打光（自定义节点） |\n| `character_edit_*` | 角色编辑（人偶化/改变ID/保留ID，自定义节点） |\n| `creature_*` | 生物控制（表情/运动，自定义节点） |\n\n**视频节点建议**：模型 `kling` + `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n### Prompt @占位符\n\nprompt 中可用 `@参考图`、`@首帧图1`、`@尾帧图1`、`@参考视频`、`@参考音频` 引用上游输入。通过 `canvas:node:prompt` 命令自动转换为模型特定格式：\n\n| 模型 | `@首帧图1` → | `@尾帧图1` → | `@参考图` → |\n|------|-------------|-------------|------------|\n| `kling-video-o1` | `<<<image_1>>>` | `<<<image_2>>>` | `<<<image_1>>>` |\n| `viduq2-pro` | `@1` | `@2` | `@1` |\n| 其他 | `第一张首帧图` | `第一张尾帧图` | `第一张参考图` |\n\n用法：先调用 `canvas:node:prompt` 获取 `resolved` 字段，再写入节点。需连线已建立且上游已完成。\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | 重新获取后 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败 | 重试 2-3 次，间隔 3-5 秒 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --id <id>` 查看 |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\nFile v1.0.15:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.15\",\n  \"publishedAt\": 1776775799793\n}\n\nArchive v1.0.14: 2 files, 5073 bytes\n\nFiles: SKILL.md (10926b), _meta.json (130b)\n\nFile v1.0.14:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）\n```\n\n`project:switch` 自动解析 workspace 的规则（仅依赖 `userId`，不依赖 `username`，因为 username 是用户可自定义的别名）：\n1. **精确匹配**：`/{projectId}/用户空间/` 下目录名以 `_{userId}` 结尾\n2. **模糊匹配**：目录名包含 `userId`\n3. 均未命中则清空 `defaultWorkspace`，需手动设置\n\n也可手动设置：\n```bash\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n| `project:list` | 列出项目 |\n| `project:switch <projectId>` | 切换项目（自动更新 defaultProject + defaultWorkspace，workspace 匹配仅依赖 `userId`，不依赖 `username`），可选 `--no-workspace` |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:upload --local-file <本地路径> --file-path <ZenFS路径> --project-id <id>` | 上传本地文件到 COS 并注册到 ZenFS，可选 `--title` |\n\n### 画布管理（标 `[S]` 的命令需先 `canvas:open`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布，可选 `--list-path` |\n| `canvas:open --canvas <path>` | 打开画布（启动 Session） |\n| `canvas:info` `[S]` | 查看画布信息 |\n| `canvas:save` `[S]` | 手动保存（一般不需要，见下方说明） |\n| `canvas:run --node <id>` `[S]` | 运行节点，`--wait` 同步等待（默认超时 10 分钟） |\n\n### 节点操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list` | 列出所有节点 |\n| `canvas:node:info --id <id>` | 节点详情（含 taskId/taskStatus） |\n| `canvas:node:add <type>` | 添加节点，可选 `--name --position \"x,y\"` |\n| `canvas:node:remove --id <id>` | 删除节点 |\n| `canvas:node:props --id <id>` | 修改节点自身属性，可选 `--name`（标题）`--position \"x,y\"`（位置） |\n| `canvas:node:set --id <id>` | 设置参数（推荐 `--options-json`） |\n| `canvas:node:prompt --id <id> --prompt <text>` | 解析 prompt 中 @占位符，可选 `--model` |\n\n多节点时用 `--position \"x,y\"` 避免重叠，建议水平间隔 400px。\n\n### 连线操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list` | 列出所有连线 |\n| `canvas:edge:add` | 连线（`--source --source-handle --target --target-handle`） |\n| `canvas:edge:remove --id <id>` | 删除连线 |\n\n### 查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `node:list` | 所有可用节点类型定义（本地） |\n| `node:defs` | 完整节点定义含模型信息（需认证） |\n| `node:model <nodeType>` | 节点支持的模型列表（需认证） |\n| `task:status <taskId> --canvas-id <id>` | 查询任务状态 |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`--source-handle` 和 `--target-handle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:props`、`canvas:node:set`、`canvas:edge:add`、`canvas:edge:remove` 执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```bash\n# 0. 认证（一次性）\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 打开画布\nzenvfx canvas:open --canvas \"${CANVAS_PATH}.canvas\"\n\n# 3. 添加节点\nRESULT=$(zenvfx canvas:node:add normal_video_generator --name \"文生视频\" --position \"0,0\" --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 4. 设置参数（model/clarity 等值须通过 node:model <type> 动态查询，勿硬编码）\nzenvfx canvas:node:set --id $NODE_ID --options-json \\\n  '{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}' \\\n  --canvas \"${CANVAS_PATH}\"\n\n# 5. 运行并等待（推荐 --wait，超时 30 分钟）\nzenvfx canvas:run --node $NODE_ID --canvas \"${CANVAS_PATH}\" --wait --timeout 1800000 2>/dev/null\n# 返回: {\"status\":\"completed\",\"outputs\":[{\"url\":\"...\"}]}\n```\n\n**异步模式**：不加 `--wait` 立即返回 `taskId`，再用 `task:status <taskId> --canvas-id <canvasId>` 轮询（建议 10 秒间隔，30 分钟超时）。`canvasId` 通过 `file:path-to-id --path \"${CANVAS_PATH}.canvas\"` 获取。\n\n---\n\n## 节点参数\n\n通过 `--options-json` 统一传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n常用节点类型：\n\n| nodeUiType | 说明 |\n|---|---|\n| `normal_video_generator` | 文生视频 / 图生视频 / 图片参考 |\n| `image_generator` | 文生图 / 图生图 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 / 视频参考 / 动作迁移 |\n| `comprehensive_reference_generator` | 全能参考生视频（支持图/视频/音频混合输入） |\n| `llm` | 大模型节点（多模态理解，支持 Claude / Gemini / GPT） |\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点 |\n| `scene_rerender_*` | 场景转绘（首帧/尾帧/首尾帧，自定义节点） |\n| `video_relighting_*` | 视频重打光（自定义节点） |\n| `character_edit_*` | 角色编辑（人偶化/改变ID/保留ID，自定义节点） |\n| `creature_*` | 生物控制（表情/运动，自定义节点） |\n\n**视频节点建议**：模型 `kling` + `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n### Prompt @占位符\n\nprompt 中可用 `@参考图`、`@首帧图1`、`@尾帧图1`、`@参考视频`、`@参考音频` 引用上游输入。通过 `canvas:node:prompt` 命令自动转换为模型特定格式：\n\n| 模型 | `@首帧图1` → | `@尾帧图1` → | `@参考图` → |\n|------|-------------|-------------|------------|\n| `kling-video-o1` | `<<<image_1>>>` | `<<<image_2>>>` | `<<<image_1>>>` |\n| `viduq2-pro` | `@1` | `@2` | `@1` |\n| 其他 | `第一张首帧图` | `第一张尾帧图` | `第一张参考图` |\n\n用法：先调用 `canvas:node:prompt` 获取 `resolved` 字段，再写入节点。需连线已建立且上游已完成。\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | 重新获取后 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败 | 重试 2-3 次，间隔 3-5 秒 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --id <id>` 查看 |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\nFile v1.0.14:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.14\",\n  \"publishedAt\": 1776773094448\n}\n\nArchive v1.0.13: 2 files, 4832 bytes\n\nFiles: SKILL.md (10258b), _meta.json (130b)\n\nFile v1.0.13:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:upload --local-file <本地路径> --file-path <ZenFS路径> --project-id <id>` | 上传本地文件到 COS 并注册到 ZenFS，可选 `--title` |\n| `project:list` | 列出项目 |\n\n### 画布管理（标 `[S]` 的命令需先 `canvas:open`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布，可选 `--list-path` |\n| `canvas:open --canvas <path>` | 打开画布（启动 Session） |\n| `canvas:info` `[S]` | 查看画布信息 |\n| `canvas:save` `[S]` | 手动保存（一般不需要，见下方说明） |\n| `canvas:run --node <id>` `[S]` | 运行节点，`--wait` 同步等待（默认超时 10 分钟） |\n\n### 节点操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list` | 列出所有节点 |\n| `canvas:node:info --id <id>` | 节点详情（含 taskId/taskStatus） |\n| `canvas:node:add <type>` | 添加节点，可选 `--name --position \"x,y\"` |\n| `canvas:node:remove --id <id>` | 删除节点 |\n| `canvas:node:edit --id <id>` | 编辑节点属性，可选 `--name`（标题）`--position \"x,y\"`（位置） |\n| `canvas:node:set --id <id>` | 设置参数（推荐 `--options-json`） |\n| `canvas:node:prompt --id <id> --prompt <text>` | 解析 prompt 中 @占位符，可选 `--model` |\n\n多节点时用 `--position \"x,y\"` 避免重叠，建议水平间隔 400px。\n\n### 连线操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list` | 列出所有连线 |\n| `canvas:edge:add` | 连线（`--source --source-handle --target --target-handle`） |\n| `canvas:edge:remove --id <id>` | 删除连线 |\n\n### 查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `node:list` | 所有可用节点类型定义（本地） |\n| `node:defs` | 完整节点定义含模型信息（需认证） |\n| `node:model <nodeType>` | 节点支持的模型列表（需认证） |\n| `task:status <taskId> --canvas-id <id>` | 查询任务状态 |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`--source-handle` 和 `--target-handle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:edit`、`canvas:node:set`、`canvas:edge:add`、`canvas:edge:remove` 执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```bash\n# 0. 认证（一次性）\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 打开画布\nzenvfx canvas:open --canvas \"${CANVAS_PATH}.canvas\"\n\n# 3. 添加节点\nRESULT=$(zenvfx canvas:node:add normal_video_generator --name \"文生视频\" --position \"0,0\" --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 4. 设置参数（model/clarity 等值须通过 node:model <type> 动态查询，勿硬编码）\nzenvfx canvas:node:set --id $NODE_ID --options-json \\\n  '{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}' \\\n  --canvas \"${CANVAS_PATH}\"\n\n# 5. 运行并等待（推荐 --wait，超时 30 分钟）\nzenvfx canvas:run --node $NODE_ID --canvas \"${CANVAS_PATH}\" --wait --timeout 1800000 2>/dev/null\n# 返回: {\"status\":\"completed\",\"outputs\":[{\"url\":\"...\"}]}\n```\n\n**异步模式**：不加 `--wait` 立即返回 `taskId`，再用 `task:status <taskId> --canvas-id <canvasId>` 轮询（建议 10 秒间隔，30 分钟超时）。`canvasId` 通过 `file:path-to-id --path \"${CANVAS_PATH}.canvas\"` 获取。\n\n---\n\n## 节点参数\n\n通过 `--options-json` 统一传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n常用节点类型：\n\n| nodeUiType | 说明 |\n|---|---|\n| `normal_video_generator` | 文生视频 / 图生视频 / 图片参考 |\n| `image_generator` | 文生图 / 图生图 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 / 视频参考 / 动作迁移 |\n| `comprehensive_reference_generator` | 全能参考生视频（支持图/视频/音频混合输入） |\n| `llm` | 大模型节点（多模态理解，支持 Claude / Gemini / GPT） |\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点 |\n| `scene_rerender_*` | 场景转绘（首帧/尾帧/首尾帧，自定义节点） |\n| `video_relighting_*` | 视频重打光（自定义节点） |\n| `character_edit_*` | 角色编辑（人偶化/改变ID/保留ID，自定义节点） |\n| `creature_*` | 生物控制（表情/运动，自定义节点） |\n\n**视频节点建议**：模型 `kling` + `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n### Prompt @占位符\n\nprompt 中可用 `@参考图`、`@首帧图1`、`@尾帧图1`、`@参考视频`、`@参考音频` 引用上游输入。通过 `canvas:node:prompt` 命令自动转换为模型特定格式：\n\n| 模型 | `@首帧图1` → | `@尾帧图1` → | `@参考图` → |\n|------|-------------|-------------|------------|\n| `kling-video-o1` | `<<<image_1>>>` | `<<<image_2>>>` | `<<<image_1>>>` |\n| `viduq2-pro` | `@1` | `@2` | `@1` |\n| 其他 | `第一张首帧图` | `第一张尾帧图` | `第一张参考图` |\n\n用法：先调用 `canvas:node:prompt` 获取 `resolved` 字段，再写入节点。需连线已建立且上游已完成。\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | 重新获取后 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败 | 重试 2-3 次，间隔 3-5 秒 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --id <id>` 查看 |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\nFile v1.0.13:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.13\",\n  \"publishedAt\": 1776769994589\n}\n\nArchive v1.0.12: 2 files, 4790 bytes\n\nFiles: SKILL.md (10123b), _meta.json (130b)\n\nFile v1.0.12:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:upload --local-file <本地路径> --file-path <ZenFS路径> --project-id <id>` | 上传本地文件到 COS 并注册到 ZenFS，可选 `--title` |\n| `project:list` | 列出项目 |\n\n### 画布管理（标 `[S]` 的命令需先 `canvas:open`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布，可选 `--list-path` |\n| `canvas:open --canvas <path>` | 打开画布（启动 Session） |\n| `canvas:info` `[S]` | 查看画布信息 |\n| `canvas:save` `[S]` | 手动保存（一般不需要，见下方说明） |\n| `canvas:run --node <id>` `[S]` | 运行节点，`--wait` 同步等待（默认超时 10 分钟） |\n\n### 节点操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list` | 列出所有节点 |\n| `canvas:node:info --id <id>` | 节点详情（含 taskId/taskStatus） |\n| `canvas:node:add <type>` | 添加节点，可选 `--name --position \"x,y\"` |\n| `canvas:node:remove --id <id>` | 删除节点 |\n| `canvas:node:set --id <id>` | 设置参数（推荐 `--options-json`） |\n| `canvas:node:prompt --id <id> --prompt <text>` | 解析 prompt 中 @占位符，可选 `--model` |\n\n多节点时用 `--position \"x,y\"` 避免重叠，建议水平间隔 400px。\n\n### 连线操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list` | 列出所有连线 |\n| `canvas:edge:add` | 连线（`--source --source-handle --target --target-handle`） |\n| `canvas:edge:remove --id <id>` | 删除连线 |\n\n### 查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `node:list` | 所有可用节点类型定义（本地） |\n| `node:defs` | 完整节点定义含模型信息（需认证） |\n| `node:model <nodeType>` | 节点支持的模型列表（需认证） |\n| `task:status <taskId> --canvas-id <id>` | 查询任务状态 |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`--source-handle` 和 `--target-handle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:set`、`canvas:edge:add`、`canvas:edge:remove` 执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```bash\n# 0. 认证（一次性）\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 打开画布\nzenvfx canvas:open --canvas \"${CANVAS_PATH}.canvas\"\n\n# 3. 添加节点\nRESULT=$(zenvfx canvas:node:add normal_video_generator --name \"文生视频\" --position \"0,0\" --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 4. 设置参数（model/clarity 等值须通过 node:model <type> 动态查询，勿硬编码）\nzenvfx canvas:node:set --id $NODE_ID --options-json \\\n  '{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}' \\\n  --canvas \"${CANVAS_PATH}\"\n\n# 5. 运行并等待（推荐 --wait，超时 30 分钟）\nzenvfx canvas:run --node $NODE_ID --canvas \"${CANVAS_PATH}\" --wait --timeout 1800000 2>/dev/null\n# 返回: {\"status\":\"completed\",\"outputs\":[{\"url\":\"...\"}]}\n```\n\n**异步模式**：不加 `--wait` 立即返回 `taskId`，再用 `task:status <taskId> --canvas-id <canvasId>` 轮询（建议 10 秒间隔，30 分钟超时）。`canvasId` 通过 `file:path-to-id --path \"${CANVAS_PATH}.canvas\"` 获取。\n\n---\n\n## 节点参数\n\n通过 `--options-json` 统一传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n常用节点类型：\n\n| nodeUiType | 说明 |\n|---|---|\n| `normal_video_generator` | 文生视频 / 图生视频 / 图片参考 |\n| `image_generator` | 文生图 / 图生图 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 / 视频参考 / 动作迁移 |\n| `comprehensive_reference_generator` | 全能参考生视频（支持图/视频/音频混合输入） |\n| `llm` | 大模型节点（多模态理解，支持 Claude / Gemini / GPT） |\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点 |\n| `scene_rerender_*` | 场景转绘（首帧/尾帧/首尾帧，自定义节点） |\n| `video_relighting_*` | 视频重打光（自定义节点） |\n| `character_edit_*` | 角色编辑（人偶化/改变ID/保留ID，自定义节点） |\n| `creature_*` | 生物控制（表情/运动，自定义节点） |\n\n**视频节点建议**：模型 `kling` + `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n### Prompt @占位符\n\nprompt 中可用 `@参考图`、`@首帧图1`、`@尾帧图1`、`@参考视频`、`@参考音频` 引用上游输入。通过 `canvas:node:prompt` 命令自动转换为模型特定格式：\n\n| 模型 | `@首帧图1` → | `@尾帧图1` → | `@参考图` → |\n|------|-------------|-------------|------------|\n| `kling-video-o1` | `<<<image_1>>>` | `<<<image_2>>>` | `<<<image_1>>>` |\n| `viduq2-pro` | `@1` | `@2` | `@1` |\n| 其他 | `第一张首帧图` | `第一张尾帧图` | `第一张参考图` |\n\n用法：先调用 `canvas:node:prompt` 获取 `resolved` 字段，再写入节点。需连线已建立且上游已完成。\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | 重新获取后 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败 | 重试 2-3 次，间隔 3-5 秒 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --id <id>` 查看 |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\nFile v1.0.12:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.12\",\n  \"publishedAt\": 1776766702258\n}\n\nArchive v1.0.11: 2 files, 4788 bytes\n\nFiles: SKILL.md (10123b), _meta.json (130b)\n\nFile v1.0.11:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:upload --local-file <本地路径> --file-path <ZenFS路径> --project-id <id>` | 上传本地文件到 COS 并注册到 ZenFS，可选 `--title` |\n| `project:list` | 列出项目 |\n\n### 画布管理（标 `[S]` 的命令需先 `canvas:open`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布，可选 `--list-path` |\n| `canvas:open --canvas <path>` | 打开画布（启动 Session） |\n| `canvas:info` `[S]` | 查看画布信息 |\n| `canvas:save` `[S]` | 手动保存（一般不需要，见下方说明） |\n| `canvas:run --node <id>` `[S]` | 运行节点，`--wait` 同步等待（默认超时 10 分钟） |\n\n### 节点操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list` | 列出所有节点 |\n| `canvas:node:info --id <id>` | 节点详情（含 taskId/taskStatus） |\n| `canvas:node:add <type>` | 添加节点，可选 `--name --position \"x,y\"` |\n| `canvas:node:remove --id <id>` | 删除节点 |\n| `canvas:node:set --id <id>` | 设置参数（推荐 `--options-json`） |\n| `canvas:node:prompt --id <id> --prompt <text>` | 解析 prompt 中 @占位符，可选 `--model` |\n\n多节点时用 `--position \"x,y\"` 避免重叠，建议水平间隔 400px。\n\n### 连线操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list` | 列出所有连线 |\n| `canvas:edge:add` | 连线（`--source --source-handle --target --target-handle`） |\n| `canvas:edge:remove --id <id>` | 删除连线 |\n\n### 查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `node:list` | 所有可用节点类型定义（本地） |\n| `node:defs` | 完整节点定义含模型信息（需认证） |\n| `node:model <nodeType>` | 节点支持的模型列表（需认证） |\n| `task:status <taskId> --canvas-id <id>` | 查询任务状态 |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`--source-handle` 和 `--target-handle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:set`、`canvas:edge:add`、`canvas:edge:remove` 执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```bash\n# 0. 认证（一次性）\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 打开画布\nzenvfx canvas:open --canvas \"${CANVAS_PATH}.canvas\"\n\n# 3. 添加节点\nRESULT=$(zenvfx canvas:node:add normal_video_generator --name \"文生视频\" --position \"0,0\" --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 4. 设置参数（model/clarity 等值须通过 node:model <type> 动态查询，勿硬编码）\nzenvfx canvas:node:set --id $NODE_ID --options-json \\\n  '{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}' \\\n  --canvas \"${CANVAS_PATH}\"\n\n# 5. 运行并等待（推荐 --wait，超时 30 分钟）\nzenvfx canvas:run --node $NODE_ID --canvas \"${CANVAS_PATH}\" --wait --timeout 1800000 2>/dev/null\n# 返回: {\"status\":\"completed\",\"outputs\":[{\"url\":\"...\"}]}\n```\n\n**异步模式**：不加 `--wait` 立即返回 `taskId`，再用 `task:status <taskId> --canvas-id <canvasId>` 轮询（建议 10 秒间隔，30 分钟超时）。`canvasId` 通过 `file:path-to-id --path \"${CANVAS_PATH}.canvas\"` 获取。\n\n---\n\n## 节点参数\n\n通过 `--options-json` 统一传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n常用节点类型：\n\n| nodeUiType | 说明 |\n|---|---|\n| `normal_video_generator` | 文生视频 / 图生视频 / 图片参考 |\n| `image_generator` | 文生图 / 图生图 |\n| `first_to_last_video_generator` | 首尾帧视频 |\n| `composite_video_generator` | 视频编辑 / 视频参考 / 动作迁移 |\n| `comprehensive_reference_generator` | 全能参考生视频（支持图/视频/音频混合输入） |\n| `llm` | 大模型节点（多模态理解，支持 Claude / Gemini / GPT） |\n| `text_input` / `image_input` / `video_input` / `audio_input` | 输入节点 |\n| `scene_rerender_*` | 场景转绘（首帧/尾帧/首尾帧，自定义节点） |\n| `video_relighting_*` | 视频重打光（自定义节点） |\n| `character_edit_*` | 角色编辑（人偶化/改变ID/保留ID，自定义节点） |\n| `creature_*` | 生物控制（表情/运动，自定义节点） |\n\n**视频节点建议**：模型 `kling` + `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n### Prompt @占位符\n\nprompt 中可用 `@参考图`、`@首帧图1`、`@尾帧图1`、`@参考视频`、`@参考音频` 引用上游输入。通过 `canvas:node:prompt` 命令自动转换为模型特定格式：\n\n| 模型 | `@首帧图1` → | `@尾帧图1` → | `@参考图` → |\n|------|-------------|-------------|------------|\n| `kling-video-o1` | `<<<image_1>>>` | `<<<image_2>>>` | `<<<image_1>>>` |\n| `viduq2-pro` | `@1` | `@2` | `@1` |\n| 其他 | `第一张首帧图` | `第一张尾帧图` | `第一张参考图` |\n\n用法：先调用 `canvas:node:prompt` 获取 `resolved` 字段，再写入节点。需连线已建立且上游已完成。\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | 重新获取后 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败 | 重试 2-3 次，间隔 3-5 秒 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --id <id>` 查看 |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pid) 2>/dev/null\nrm -f ~/.config/zenvfx/daemon.sock ~/.config/zenvfx/daemon.pid\n```\n\nFile v1.0.11:_meta.json\n\n{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.11\",\n  \"publishedAt\": 1776761416818\n}\n\nArchive v1.0.10: 2 files, 4431 bytes\n\nFiles: SKILL.md (9256b), _meta.json (130b)\n\nFile v1.0.10:SKILL.md\n\n---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n---\n\n## 认证与安装\n\n```bash\n# 安装\nnpm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\"\n```\n\n也可通过环境变量：`ZENVFX_MCP_TOKEN`、`ZENVFX_PROJECT`\n\n---\n\n## 命令速查\n\n### 配置\n\n| 命令 | 用途 |\n|------|------|\n| `auth:login <token>` | 一键认证，可选 `--host` |\n| `config:set <key> <value>` | 手动设置（key：`host`/`wsHost`/`mcpToken`/`defaultProject`/`defaultUsername`/`defaultUserId`/`defaultWorkspace`） |\n| `config:get <key>` / `config:list` | 读取配置 |\n\n### 文件系统（路径格式：`/<projectId>/目录/文件名`）\n\n| 命令 | 用途 |\n|------|------|\n| `file:stat --path <p>` | 文件/目录详情 |\n| `file:readdir --path <p>` | 目录内容（不递归） |\n| `file:mkdir --path <p>` | 创建目录（默认递归） |\n| `file:rm --path <p>` | 删除文件/目录 |\n| `file:tree --path <p>` | 目录树，可选 `--max-depth` |\n| `file:path-to-id --path <p>` | 路径转内部 ID |\n| `file:upload` | 上传本地文件 |\n| `project:list` | 列出项目 |\n\n### 画布管理（标 `[S]` 的命令需先 `canvas:open`）\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:create --name <名称>` | 创建画布，可选 `--path`（默认 `defaultWorkspace`） |\n| `canvas:list` | 列出画布，可选 `--list-path` |\n| `canvas:open --canvas <path>` | 打开画布（启动 Session） |\n| `canvas:info` `[S]` | 查看画布信息 |\n| `canvas:save` `[S]` | 手动保存（一般不需要，见下方说明） |\n| `canvas:run --node <id>` `[S]` | 运行节点，`--wait` 同步等待（默认超时 10 分钟） |\n\n### 节点操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:node:list` | 列出所有节点 |\n| `canvas:node:info --id <id>` | 节点详情（含 taskId/taskStatus） |\n| `canvas:node:add <type>` | 添加节点，可选 `--name --position \"x,y\"` |\n| `canvas:node:remove --id <id>` | 删除节点 |\n| `canvas:node:set --id <id>` | 设置参数（推荐 `--options-json`） |\n| `canvas:node:prompt --id <id> --prompt <text>` | 解析 prompt 中 @占位符，可选 `--model` |\n\n多节点时用 `--position \"x,y\"` 避免重叠，建议水平间隔 400px。\n\n### 连线操作 `[S]`\n\n| 命令 | 用途 |\n|------|------|\n| `canvas:edge:list` | 列出所有连线 |\n| `canvas:edge:add` | 连线（`--source --source-handle --target --target-handle`） |\n| `canvas:edge:remove --id <id>` | 删除连线 |\n\n### 查询（不需 Session）\n\n| 命令 | 用途 |\n|------|------|\n| `node:list` | 所有可用节点类型定义（本地） |\n| `node:defs` | 完整节点定义含模型信息（需认证） |\n| `node:model <nodeType>` | 节点支持的模型列表（需认证） |\n| `task:status <taskId> --canvas-id <id>` | 查询任务状态 |\n\n### 守护进程\n\n| 命令 | 用途 |\n|------|------|\n| `daemon:ping` / `daemon:status` / `daemon:stop` | 检测/查看/停止 daemon |\n\n---\n\n## 重要规则\n\n### 1. 连线 handle 必须使用 pinName\n\n`--source-handle` 和 `--target-handle` **必须用节点定义中的 pinName**，不是后端 API 的 field_path。用错会导致连线保存成功但前端不显示。\n\n通过 `node:list` 或 `node:defs` 查询正确的 pinName。常用速查：\n\n| 节点类型 | 输入 pinName | 输出 pinName |\n|----------|-------------|-------------|\n| `image_generator` | `prompt`, `referenceImage` | `outputImage` |\n| `normal_video_generator` | `referenceImage`, `prompt` | `outputVideo` |\n| `composite_video_generator` | `inputVideo`, `inputImage`, `prompt` | `outputVideo` |\n| `first_to_last_video_generator` | `firstReferenceImage`, `lastReferenceImage`, `prompt` | `outputVideo` |\n| `comprehensive_reference_generator` | `inputVideo`, `inputImage`, `inputAudio`, `prompt` | `outputVideo` |\n\n### 2. 编辑命令自动保存 — 不要重复 save\n\n`canvas:node:add`、`canvas:node:remove`、`canvas:node:set`、`canvas:edge:add`、`canvas:edge:remove` 执行成功后**自动保存画布**，无需额外调用 `canvas:save`。\n\n### 3. 画布路径\n\n`canvas:create` 返回的 `canvasPath` 不含 `.canvas` 后缀，canvas 类命令带不带后缀均可。`file:stat` 等文件命令需要完整文件名（带 `.canvas`）。\n\n---\n\n## 核心流程：生成 AI 视频\n\n```bash\n# 0. 认证（一次性）\nzenvfx auth:login <your-mcp-token>\n\n# 1. 创建画布\nCREATE_RESULT=$(zenvfx canvas:create --name \"测试画布\" 2>/dev/null)\nCANVAS_PATH=$(echo $CREATE_RESULT | grep -o '\"canvasPath\":\"[^\"]*\"' | sed 's/\"canvasPath\":\"//;s/\"$//')\n\n# 2. 打开画布\nzenvfx canvas:open --canvas \"${CANVAS_PATH}.canvas\"\n\n# 3. 添加节点\nRESULT=$(zenvfx canvas:node:add normal_video_generator --name \"文生视频\" --position \"0,0\" --canvas \"${CANVAS_PATH}\" 2>/dev/null)\nNODE_ID=$(echo $RESULT | grep -o '\"id\":\"[^\"]*\"' | head -1 | sed 's/\"id\":\"//;s/\"$//')\n\n# 4. 设置参数（model/clarity 等值须通过 node:model <type> 动态查询，勿硬编码）\nzenvfx canvas:node:set --id $NODE_ID --options-json \\\n  '{\"prompt\":\"傍晚的海边，小孩子嬉戏玩水\",\"model\":\"kling\",\"clarity\":\"RESOLUTION_720P\",\"ratio\":\"16:9\",\"duration\":5}' \\\n  --canvas \"${CANVAS_PATH}\"\n\n# 5. 运行并等待（推荐 --wait，超时 30 分钟）\nzenvfx canvas:run --node $NODE_ID --canvas \"${CANVAS_PATH}\" --wait --timeout 1800000 2>/dev/null\n# 返回: {\"status\":\"completed\",\"outputs\":[{\"url\":\"...\"}]}\n```\n\n**异步模式**：不加 `--wait` 立即返回 `taskId`，再用 `task:status <taskId> --canvas-id <canvasId>` 轮询（建议 10 秒间隔，30 分钟超时）。`canvasId` 通过 `file:path-to-id --path \"${CANVAS_PATH}.canvas\"` 获取。\n\n---\n\n## 节点参数\n\n通过 `--options-json` 统一传参：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `prompt` | string | 提示词 |\n| `model` | string | 模型 ID（**必须通过 `node:model <type>` 查询**） |\n| `clarity` | string | 分辨率枚举 |\n| `ratio` | string | 画幅比例 |\n| `duration` | number | 时长秒数（仅视频节点） |\n\n常用节点类型：`normal_video_generator`、`image_generator`、`composite_video_generator`、`first_to_last_video_generator`\n\n**视频节点建议**：模型 `kling` + `RESOLUTION_720P`（比 1080P 快 2-3 倍）。\n\n### Prompt @占位符\n\nprompt 中可用 `@参考图`、`@首帧图1`、`@尾帧图1`、`@参考视频`、`@参考音频` 引用上游输入。通过 `canvas:node:prompt` 命令自动转换为模型特定格式：\n\n| 模型 | `@首帧图1` → | `@尾帧图1` → | `@参考图` → |\n|------|-------------|-------------|------------|\n| `kling-video-o1` | `<<<image_1>>>` | `<<<image_2>>>` | `<<<image_1>>>` |\n| `viduq2-pro` | `@1` | `@2` | `@1` |\n| 其他 | `第一张首帧图` | `第一张尾帧图` | `第一张参考图` |\n\n用法：先调用 `canvas:node:prompt` 获取 `resolved` 字段，再写入节点。需连线已建立且上游已完成。\n\n---\n\n## 异常处理\n\n| 错误码 | 含义 | 解决方案 |\n|--------|------|----------|\n| `AUTH_REQUIRED` | Token 未配置 | `auth:login <token>` |\n| `MCP_TOKEN_INVALID` | Token 无效/过期 | 重新获取后 `auth:login` |\n| `CANVAS_NOT_FOUND` | 画布不存在 | 检查路径，`file:stat` 确认 |\n| `CANVAS_SAVE_FAILED` | 保存失败 | 重试 2-3 次，间隔 3-5 秒 |\n| `NODE_NOT_FOUND` | 节点不存在 | `canvas:node:list` 确认 |\n| `OPTION_NOT_FOUND` | 无该选项 | `canvas:node:info --id <id>` 查看 |\n| `DAEMON_TIMEOUT` | daemon 超时 | `daemon:stop` 后重试 |\n| `TASK_SUBMIT_FAILED` | 任务提交失败 | 检查节点参数 |\n\n**daemon 异常强制清理**：\n```bash\nzenvfx daemon:stop\nkill $(cat ~/.config/zenvfx/daemon.pi","readmeExcerpt":"Skill: ZenVFX CLI Owner: lenzli Summary: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include... Tags: latest:1.0.19 Version history: v1.0.19 | 2026-06-16T07:03:06.861Z | user No changes detected for version 1.0.19 (no file changes). v1.0.18 | 2026-06-16T06:33:44.446Z | user - No file changes detected in this rele","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# 首次安装 或 升级到 registry 上的最新版（@latest 等价于不写 tag）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 升级到指定版本\nnpm install -g @tencent/zenvfx-cli@0.9.1 --registry https://mirrors.tencent.com/npm/"},{"language":"bash","snippet":"# 1. 本地已安装版本\nzenvfx --version\n# 输出形如：@tencent/zenvfx-cli/0.9.1 linux-x64 node-v20.x\n\n# 2. registry 上当前 latest 版本\nnpm view @tencent/zenvfx-cli version --registry=https://mirrors.tencent.com/npm/\n# 输出形如：0.9.1\n\n# 3. 全局安装包元信息（确认安装路径与版本，排除多版本污染）\nnpm ls -g @tencent/zenvfx-cli --registry=https://mirrors.tencent.com/npm/"},{"language":"bash","snippet":"# 安装（详见上一节\"版本与升级\"）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n\n# 仅校验 token（不切换默认项目/workspace）\nzenvfx auth:verify <token>"},{"language":"bash","snippet":"zenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）"},{"language":"bash","snippet":"zenvfx config:set defaultProject <project-id>\nzenvfx config:set defaultWorkspace \"/<project-id>/用户空间/xxx\""},{"language":"json","snippet":"{\n    \"submitted\": true,\n    \"mode\": \"sync\",\n    \"timedOut\": false,\n    \"elapsed\": 62025,\n    \"results\": [\n      { \"taskId\": \"...\", \"status\": \"completed\", \"nodes\": [{ \"nodeId\": \"...\", \"status\": \"completed\", \"outputs\": [...], \"textOutputs\": [] }] }\n    ]\n  }"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: zenvfx-cli\ndescription: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include \"画布\", \"视频生成\", \"zenvfx\", \"canvas\", \"node\", \"AI视频\", \"文生视频\".\nmetadata: {\"openclaw\": {\"emoji\": \"🎬\", \"os\": [\"darwin\", \"linux\"], \"requires\": {\"bins\": [\"zenvfx\"], \"env\": [\"ZENVFX_MCP_TOKEN\"]}, \"primaryEnv\": \"ZENVFX_MCP_TOKEN\", \"install\": [{\"id\": \"npm\", \"kind\": \"command\", \"command\": \"npm install -g @tencent/zenvfx-cli --registry https://mirrors.tencent.com/npm/\", \"bins\": [\"zenvfx\"], \"label\": \"Install ZenVFX CLI (npm)\"}]}}\n---\n\n# ZenVFX CLI Skill\n\n## 概述\n\nZenVFX CLI 是 AI 视频创作平台的命令行工具，通过画布（Canvas）中的节点（Node）+ 连线（Edge）构建 AI 生成任务。\n\n- **CLI 入口**：`zenvfx <command>`\n- **输出协议**：stdout 纯 JSON（`{\"ok\":true,\"data\":{...}}` / `{\"ok\":false,\"error\":{...}}`），解析时用 `2>/dev/null` 过滤 stderr\n- **优先级**：系统中若同时存在 `zenvfx-mcp`，**一律优先使用 `zenvfx` CLI**，不要混用两者操作同一画布\n\n**架构原则（v3）**：\n- **万物皆批处理**：所有编辑操作均接收 JSON 数组 / 逗号分隔 ID 列表，无论操作 1 个还是 N 个对象，底层统一为批量调用。\n- **运行节点支持同步/异步双模式**：`canvas:run` 默认异步，加 `--wait` 进入同步模式（daemon 内部轮询直到所有节点 completed/failed 才返回）。\n- **Partial Success**：批量操作逐项执行，某项失败不影响其余，返回 `results` 数组逐项标注状态。\n\n---\n\n## 版本与升级\n\n- **当前最新版本**：`0.9.1`\n- **包名**：`@tencent/zenvfx-cli`\n- **Registry**：`https://mirrors.tencent.com/npm/`（腾讯内网 npm 镜像）\n\n### 安装 / 升级到最新\n\n```bash\n# 首次安装 或 升级到 registry 上的最新版（@latest 等价于不写 tag）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 升级到指定版本\nnpm install -g @tencent/zenvfx-cli@0.9.1 --registry https://mirrors.tencent.com/npm/\n```\n\n> 注意：必须带 `--registry`，公网 `registry.npmjs.org` 上没有这个包。\n\n### 如何确认已经是最新版\n\n按下面三步对比，三个版本号一致即说明已装到最新：\n\n```bash\n# 1. 本地已安装版本\nzenvfx --version\n# 输出形如：@tencent/zenvfx-cli/0.9.1 linux-x64 node-v20.x\n\n# 2. registry 上当前 latest 版本\nnpm view @tencent/zenvfx-cli version --registry=https://mirrors.tencent.com/npm/\n# 输出形如：0.9.1\n\n# 3. 全局安装包元信息（确认安装路径与版本，排除多版本污染）\nnpm ls -g @tencent/zenvfx-cli --registry=https://mirrors.tencent.com/npm/\n```\n\n若 `zenvfx --version` 比 `npm view` 拿到的版本旧，重新执行上面的 `npm install -g ...@latest` 即可；若 `zenvfx` 命令找不到，检查 `npm config get prefix` 下的 `bin` 是否在 `PATH` 里。\n\n升级后建议再跑一次 `zenvfx auth:verify <token>`，确认本地配置仍然可用。\n\n---\n\n## 认证与安装\n\n```bash\n# 安装（详见上一节\"版本与升级\"）\nnpm install -g @tencent/zenvfx-cli@latest --registry https://mirrors.tencent.com/npm/\n\n# 认证（自动保存 mcpToken/defaultProject/defaultWorkspace 等配置）\nzenvfx auth:login <token>          # 可选 --host <host-url>\n\n# 仅校验 token（不切换默认项目/workspace）\nzenvfx auth:verify <token>\n```\n\n`auth:login` 返回 `saved` 字段标识各配置是否已自动设置。若 `saved.defaultProject` 或 `saved.defaultWorkspace` 为 `false`，需手动补全：\n\n```bash\nzenvfx project:list 2>/dev/null              # 查看可用项目\nzenvfx project:switch <project-id>           # 一键切换项目（自动更新 workspace）\n```\n\n`project:switch` 自动解析 workspace 的规则（仅依赖 `userId`，不依赖 `username`，因为 username 是用户可自定义的别名）：\n1. **精确匹配**：`/{projectId}/用户空间/` 下目录名以 `_{userId}` 结尾\n2. **模糊匹配**：目录名包含 `userId`\n3. 均未命中则清空 `defaultWorkspace`，需手动设置\n\n也可手动设置：\n```bash\nzenvfx config:set defaultProj"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7ah21cpv2svkbannm8tw9hz584wwbd\",\n  \"slug\": \"zenvfx-cli\",\n  \"version\": \"1.0.19\",\n  \"publishedAt\": 1781593386861\n}"},{"path":"skill-card.md","content":"## Description:\n\nUse this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[lenzli](https://clawhub.ai/user/lenzli)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and creative operators use this skill to guide agents through ZenVFX CLI setup, authentication, canvas management, node editing, task execution, and troubleshooting for AI video workflows.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill installs and relies on a global ZenVFX CLI package from the Tencent registry.\n\nMitigation: Install only from a trusted registry source and prefer a pinned CLI version for repeatable deployments.\n\nRisk: The skill uses a ZenVFX token for authentication.\n\nMitigation: Use least-privilege, rotatable tokens and avoid entering tokens where shell history or logs may capture them.\n\nRisk: The documented CLI workflows can modify or delete ZenVFX project files, canvases, nodes, and edges.\n\nMitigation: Review proposed commands before execution and require explicit confirmation before delete operations such as file or node removal.\n\nRisk: Known CLI or daemon version mismatches can cause execution failures after upgrades.\n\nMitigation: Restart the daemon after CLI upgrades and verify the installed CLI version before running video generation workflows.\n\n## Reference(s):\n\n- [ZenVFX CLI ClawHub skill page](https://clawhub.ai/lenzli/skills/zenvfx-cli)\n- [lenzli ClawHub publisher profile](https://clawhub.ai/user/lenzli)\n- [Tencent npm registry](https://mirrors.tencent.com/npm/)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration, Code, JSON]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Guidance is oriented around ZenVFX CLI commands that return JSON on stdout.]\n\n## Skill Version(s):\n\n1.0.19 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include... Skill: ZenVFX CLI Owner: lenzli Summary: Use this skill when the user needs to create AI videos, manage canvases, nodes, files, or interact with the ZenVFX platform via CLI. Trigger keywords include... Tags: latest:1.0.19 Version history: v1.0.19 | 2026-06-16T07:03:06.861Z | user No changes detected for version 1.0.19 (no file changes). v1.0.18 | 2026-06-16T06:33:44.446Z | user - No file changes detected in this rele","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1193,"uniquenessScore":48,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T05:15:25.733Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T05:15:25.733Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T07:39:56.023Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}