Agent SkillsChatCut-Inc/agent-plugin › asset-import

asset-import

GitHub

指导在ChatCut项目中导入媒体资产,根据本地文件、URL或已上传状态选择最佳路径(Browser-pane优先),确保正确处理和验证上传状态。

claude/skills/asset-import/SKILL.md ChatCut-Inc/agent-plugin

Trigger Scenarios

需要将本地视频或附件导入ChatCut项目 处理公共媒体URL的导入 检查并复用编辑器中已存在的资产

Install

npx skills add ChatCut-Inc/agent-plugin --skill asset-import -g -y
More Options

Non-standard path

npx skills add https://github.com/ChatCut-Inc/agent-plugin/tree/main/claude/skills/asset-import -g -y

Use without installing

npx skills use ChatCut-Inc/agent-plugin@asset-import

指定 Agent (Claude Code)

npx skills add ChatCut-Inc/agent-plugin --skill asset-import -a claude-code -g -y

安装 repo 全部 skill

npx skills add ChatCut-Inc/agent-plugin --all -g -y

预览 repo 内 skill

npx skills add ChatCut-Inc/agent-plugin --list

SKILL.md

Frontmatter
{
    "name": "asset-import",
    "description": "Use in Claude Code when acquiring or importing media into a ChatCut project, including local or attached videos, readable user-provided paths, files already uploaded in the editor, public media URLs, Browser-pane injection, transcription readiness, and upload fallback decisions."
}

Asset Import (Claude Code)

Select one import route first

  • Readable local file or chat attachment + Browser pane available (or can be opened): use the Browser-pane local import below. This is the default Claude Code path. Do not call import_media or run upload-media.mjs first merely because the attachment has a readable local path.
  • Browser-pane fallback: use the upload-helper route only when the Browser pane cannot be opened, the target editor page is unavailable, or the page-script/drop attempt actually fails. Do not choose the fallback preemptively.
  • Already uploaded in the ChatCut editor: discover and use the existing asset through browse_assets; do not import a duplicate.
  • Public http(s) media URL: use push_asset or download_media; do not route it through a local-file helper.

Browser-pane local import (instant import; upload state is verified)

When the editor is already open (or should be opened) in the in-app Browser pane and the source files are local paths on the user's machine, this path lands assets in the project library the moment you drop them: instant preview, timeline placement, and automatic transcription (the extracted transcription audio uploads on its own). Use it for fast local editing.

MECHANISM: the Browser pane hands local files to the visible editor through a tokenized loopback URL and a synthetic OS-file drop. Current deployments may treat the pane as a normal web import, while older deployments could leave the original bytes local-only after transcription audio upload. Do not assume either behavior. After dropping, check browse_assets: if the asset reports uploading/cloud-backed, treat it as a normal web import and wait on track_progress target:"upload" before byte-dependent work; if it reports local-only/deferred original upload, follow the deferred-upload guidance below.

Consequence for sequencing: if the task will end in cloud export/share, pull_asset, or remote frame decode, use browse_assets to confirm whether the pane-dropped asset is cloud-backed. If it remains local-only when byte-dependent work is actually needed, import the same file through the upload-media.mjs helper flow below (it registers a cloud-backed asset). Do not choose the helper from the start solely because later work may need cloud bytes. Fall back to the helper flow entirely when there is no Browser pane, the editor tab is not open, or page scripting fails.

  1. Ensure the editor tab is open in the Browser pane on the target project. Use the returned browserHandoff.url when present; it is the authenticated Claude Code in-app-browser URL. Preserve returned query parameters such as dockviewLayout=media, but do not add theme=codex or invent Codex-only workbench parameters for Claude Code URLs.
  2. Start the tokenized loopback file server bundled with this skill (auto-shuts down after --ttl seconds; serves only the listed files, only to the editor origin):
node <this-skill-dir>/scripts/serve-local-media.mjs --origin <origin-from-browserHandoff-or-editorUrl> /path/to/a.mp4 /path/to/b.mov

It prints {"files": {"a.mp4": "http://127.0.0.1:<port>/<token>/a.mp4", ...}}.

  1. In the Browser pane, run page JavaScript that fetches each URL and dispatches a synthetic OS-file drop (loopback fetches are allowed from the https editor page; the server answers CORS + Private Network Access preflights). Drop target decides placement — the ASSETS PANEL (div.relative.flex.min-h-0.flex-1.flex-col.pb-1\.5.select-none) imports to the library only; the viewer/canvas area also places the clip on the timeline at the playhead. Import to library only unless the user asked to place it:
const MIME = {
  mp4: "video/mp4",
  mov: "video/quicktime",
  webm: "video/webm",
  mp3: "audio/mpeg",
  wav: "audio/wav",
  m4a: "audio/mp4",
  png: "image/png",
  jpg: "image/jpeg",
  jpeg: "image/jpeg",
  gif: "image/gif",
};
const resp = await fetch(fileUrl);
if (!resp.ok) throw new Error("loopback fetch failed: " + resp.status);
const ext = fileName.split(".").pop().toLowerCase();
const file = new File([await resp.blob()], fileName, {
  type: MIME[ext] || "application/octet-stream",
});
const dt = new DataTransfer();
dt.items.add(file);
const target = document.querySelector(
  "div.relative.flex.min-h-0.flex-1.flex-col.pb-1\\.5.select-none",
);
if (!target)
  throw new Error("assets panel dropzone not found — is the editor loaded?");
const opts = {
  bubbles: true,
  cancelable: true,
  composed: true,
  dataTransfer: dt,
};
target.dispatchEvent(new DragEvent("dragenter", opts));
target.dispatchEvent(new DragEvent("dragover", opts));
target.dispatchEvent(new DragEvent("drop", opts));
  1. Verify with browse_assets: the asset should appear in the project with transcription starting. Wait for transcription via track_progress before transcript work, exactly as with other import paths. Check upload/local-only state separately before export, pull_asset, or remote frame decode.
  2. PIPELINE LIFECYCLE: after the drop, the editor runs a background pipeline — hash, durable local persistence, transcription-audio upload + ASR, and, on web-classified deployments, original byte upload. When the pipeline is allowed to finish, the local blob is persisted and the asset survives tab reloads. The relink failure mode appears when the pipeline is INTERRUPTED before local persistence completes: navigating the tab away, closing it, or losing the session right after importing strands the asset as relink-on-reload. (Also seen: a full local disk makes the browser storage-quota write fail, stranding the same way.) Therefore:
    • AFTER DROPPING, LEAVE THE TAB ALONE until browse_assets shows the asset registered and transcription started (typically well under a minute); do not chain an immediate navigation after an import.
    • If you find an asset in the relink state (from an earlier interrupted run), recover by re-running the same drop with the same file — cheap and scriptable; do it proactively instead of asking the user to re-pick.
    • Before byte-dependent work (export, pull_asset, remote frame decode), check browse_assets. If upload is in progress, wait on track_progress target:"upload"; if the asset is still local-only/deferred, import the file via the upload-media.mjs helper when those cloud bytes are needed (it registers a cloud-backed asset; place that assetId on the timeline).
  3. PROGRESS, VISUAL UNDERSTANDING, TRIAGE — the helper-flow rules below apply to this path verbatim, with one advantage: you SERVED these files, so you already hold every original local path.
    • Progress visibility: browse_assets shows per-asset state; track_progress {action:"status"|"wait", target:"transcription", assetIds} is the progress surface for transcript work, and track_progress target:"upload" is only for assets that are actually uploading. Tell the user exactly what you are waiting on instead of blocking silently.
    • Visual understanding: for content analysis, extract stills locally from the path you served (ffmpeg -ss <t> -i <path> -frames:v 1) and read the images natively — do NOT wait for upload or call remote inspect_asset while the local path is readable (same rule as the helper flow's sourcePath).
    • Many files: don't blanket-import a big folder. Probe locally first (ffprobe + a sampled frame per file) to see what each clip is, pick the bounded subset the task needs (ask the user when the selection is editorial), then drop just those — same judgment as the helper flow's multi-source rule; selection must not become a mandatory gate when the needed originals are obvious.

Original filenames, including CJK names, are preserved verbatim. Do not build any other ad-hoc local server or bypass: this loopback helper + synthetic drop is the only sanctioned page-injection import path.

Upload-helper fallback only

Use this section only after the Browser-pane route is unavailable or actually fails. The symlinked Codex helper is not an alternative default import route.

If the helper/upload command is denied by host policy or auto-review because it would transfer private local file contents to ChatCut's external API, stop immediately. Do not inspect, transcode, copy, edit, register local-only, render locally, or try any alternate local workflow. Tell the user that Claude Code was denied permission to upload the file, then ask them to either upload the media in the right panel ChatCut editor or rerun Claude Code with permission for this upload.

The helper is mandatory for import prep/upload. Do not run ffprobe, ffmpeg, curl, metadata inspection, extraction, transcode, or presigned-upload commands yourself as a replacement for the helper. Do not copy local media into the workspace to make push_asset accept it. The only local command you should run for import prep/upload is this skill's scripts/upload-media.mjs. Separate visual verification/source-frame inspection may use host-native local file tools such as ffmpeg; follow verification. The helper's technical media preparation is not permission to make an editorial pre-render or flattened final video locally.

MCP OAuth stays inside the MCP client. The helper uses only the short 30-minute import token returned by import_media; never pass OAuth tokens to shell. Resolve scripts/upload-media.mjs relative to this skill file; do not search the workspace.

Run upload-media.mjs with node from PATH as defined by chatcut-plugin-basics-claude. Do not install Node.js. Use Claude Code's normal shell permission flow.

Required flow for one or many readable files:

  1. Call import_media with {"action":"create_session"}.
  2. Run the plugin-provided helper once with the returned token, endpoint, and at most four local file paths. Do not call import_media again for those files. For more files, split them into batches of four and create a fresh session per batch. The helper returns registered assetIds as soon as placeholders are created; upload and transcription work may continue after the IDs are known.

For multi-source edits, build reviewable work from original source assets in the ChatCut timeline. Do not locally concatenate, pre-trim, pre-compose, burn captions, mix down, or render a "review MP4" merely to reduce the number of files uploaded. Use judgment on sequencing: start import for obvious or likely-needed originals when that keeps work moving, and inspect local source frames in parallel when helpful. Do not make a separate local source-selection pass a mandatory gate before upload. If the user explicitly asks you to choose among many sources, or importing every file is clearly unreasonable, choose a bounded subset and import those originals through this flow.

node <this-skill-dir>/scripts/upload-media.mjs --token <token> --endpoint <endpoint> /path/to/source-1.mp4 /path/to/source-2.wav

Run the helper as a normal foreground command and read its final JSON from stdout. Detached/background mode is not supported. For non-SVG media imports, the helper registers an asset placeholder before preparing and uploading bytes. SVG imports keep the direct prepare/complete path. Video imports are always transcoded and normalized to 30fps before the final media upload.

Transcription audio is prepared, uploaded, and started before the large asset byte upload whenever readable audio exists. If audio/video assets were imported, call track_progress with target:"transcription" before transcript/caption work. For source-frame inspection, prefer the helper's returned sourcePath and inspect locally with host-native tools; do not wait for upload or call inspect_asset when the original path is readable. Wait for target:"upload" only before byte-dependent work that truly requires ChatCut/cloud bytes, such as export/render, pull_asset, or remote inspect_asset for an asset whose original file path is not available.

Use precise wording when reporting progress: if the placeholder is registered, say the assetId is already known or available. If you are still waiting, say exactly what you are waiting for, such as helper output/status confirmation, transcription readiness, or byte upload completion. Do not say you are waiting for upload to finish "to get the asset id" after registration has happened.

The published plugin bundles compressed FFmpeg binaries for Apple Silicon macOS and x64 Windows. The helper resolves explicit --ffmpeg/--ffprobe arguments first, then environment overrides, then the matching bundled binaries, and finally ffmpeg/ffprobe on PATH. If the helper still reports a missing or broken media binary, first attempt to fix it yourself using available shell/package-manager capabilities. Only ask the user to install or fix FFmpeg if self-repair is unavailable, blocked, or fails. Do not guess or rewrite helper metadata.

Record source URL/path and acquisition method in trace notes when validating plugin behavior.

Version History

  • e1867a8 Current 2026-08-02 23:36
  • f39cdae 2026-07-30 21:52

Same Skill Collection

chatcut/skills/asset-import/SKILL.md
chatcut/skills/chatcut-plugin-basics-claude/SKILL.md
chatcut/skills/chatcut-plugin-basics/SKILL.md
chatcut/skills/create-motion-graphics/SKILL.md
chatcut/skills/export/SKILL.md
chatcut/skills/image-gen/SKILL.md
chatcut/skills/known-errors/SKILL.md
chatcut/skills/music/SKILL.md
chatcut/skills/shader-gen/SKILL.md
chatcut/skills/transcription/SKILL.md
chatcut/skills/verification/SKILL.md
chatcut/skills/video-gen/SKILL.md
chatcut/skills/voice/SKILL.md
chatcut/skills/widget-forms/SKILL.md
claude/skills/create-motion-graphics/SKILL.md
claude/skills/export/SKILL.md
claude/skills/image-gen/SKILL.md
claude/skills/known-errors/SKILL.md
claude/skills/motion-graphic-gen/SKILL.md
claude/skills/music/SKILL.md
claude/skills/shader-gen/SKILL.md
claude/skills/transcription/SKILL.md
claude/skills/verification/SKILL.md
claude/skills/video-gen/SKILL.md
claude/skills/voice/SKILL.md
claude/skills/widget-forms/SKILL.md
codex/skills/asset-import/SKILL.md
codex/skills/chatcut-plugin-basics/SKILL.md
codex/skills/create-motion-graphics/SKILL.md
codex/skills/export/SKILL.md
codex/skills/image-gen/SKILL.md
codex/skills/known-errors/SKILL.md
codex/skills/music/SKILL.md
codex/skills/shader-gen/SKILL.md
codex/skills/transcription/SKILL.md
codex/skills/verification/SKILL.md
codex/skills/video-gen/SKILL.md
codex/skills/voice/SKILL.md
codex/skills/widget-forms/SKILL.md
chatcut/skills/product-help/SKILL.md
chatcut/skills/talking-head-guide/SKILL.md
claude/skills/chatcut-plugin-basics-claude/SKILL.md
claude/skills/product-help/SKILL.md
claude/skills/talking-head-guide/SKILL.md
codex/skills/product-help/SKILL.md
codex/skills/talking-head-guide/SKILL.md

Metadata

Files
0
Version
e1867a8
Hash
a43dfe73
Indexed
2026-07-30 21:52

trang chủ - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-04 05:08
浙ICP备14020137号-1 $bản đồ khách truy cập$