BaoCut
SkillDev toolsBaoCut-only operator for the installed `bcut` CLI and `.bcut` projects. Implicitly trigger only when the request explicitly names BaoCut or `bcut`, targets a `.bcut` project or BaoCut Subtitle Studio, or continues a BaoCut workflow already established in the conversation. Do not trigger solely for generic audio or video, transcription, subtitles, translation, editing, animation, review, rendering or export, FFmpeg, or another NLE. Once triggered, execute and verify the requested BaoCut transcription, subtitle or timeline, overlay, review, render, or export workflow. Being inside the BaoCut source repository is not itself a trigger; ordinary code and documentation tasks follow repository instructions unless they also operate the product or a `.bcut` project.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the BaoCut skill
What this skill tells your AI
The instructions your AI receives, as published by jimliu/baocut in skills/baocut/SKILL.md and read by ahel’s review.
Use the bundled resolver for every command. On macOS/Linux:
BAOCUT_SKILL_ROOT="<this-skill-directory>"
"$BAOCUT_SKILL_ROOT/bin/baocut" --json version
On Windows, run the native PowerShell resolver (WSL is not required):
$env:BAOCUT_SKILL_ROOT = "<this-skill-directory>"
& "$env:BAOCUT_SKILL_ROOT\bin\baocut.ps1" --json version
Mandatory startup version gate
Run this gate once at the start of every BaoCut task, before spec, doctor,
any project command, or reuse of an existing bcut serve:
- Explicitly run the platform resolver's
--json versioncommand above and retain itsappVersionandcommit. A successful resolver handshake, a compatiblespec,doctor, orserve --statusis not an update check. - Immediately read and execute references/updates.md:
fetch the published appcast and compare its version numerically with the
local
appVersion. Only an unavailable appcast may be reported as skipped. - When the appcast is newer, update the standalone skill and let its refreshed resolver download, verify, and cache the pinned CLI before continuing. Do not merely report the update or keep using the compatible old CLI. Never overwrite a development checkout or an App-bundled skill; use the supported source/App update path documented in the reference instead.
- After any CLI update, run the refreshed resolver with
serve --background, thenserve --status. This idempotent start replaces an older same-root service, restores its mounts, and must report the refreshed CLI'sappVersionandcommit; also require HTTP 200 from its health endpoint. Discard any URL discovered before the restart.
Only after this gate may capability preflight and the requested work begin.
The resolver locates the right CLI on its own — never call bcut directly:
- An explicit
BAOCUT_CLI(orBCUT_EXECUTABLE/BAOCUT_BIN) override wins. Point it only at a CLI built for this machine's architecture — see the architecture guard below. - In a BaoCut development checkout (this skill directory inside the source
tree) it uses the workspace build — newest of release/debug, under
core/target/{release,debug}/bcutorcore/target/<host-triple>/…— or runs the sources viacargo runwhen nothing is built yet (it looks forcargoin~/.cargo/bin, Homebrew's rustup, and~/.rustup/toolchainswhen PATH lacks it). It prints adevelopment checkout detectednote to stderr in that case, and a separate note when it must compile from source or when it falls back to the installed App CLI because nothing is built andcargois unavailable — read those notes instead of guessing why a version gate failed. A foreign-architecture build in the tree (for examplecore/target/x86_64-apple-darwin/…on Apple Silicon) is never selected. - In a released install it uses the CLI embedded in BaoCut.app, in either
/Applicationsor~/Applications; every App release ships with its matchingbaocut-cli, so App and CLI versions always move together. - Then a
bcuton PATH. - Then the cached CLI this skill pinned earlier, under
${XDG_CACHE_HOME:-~/.cache}/baocut/cli/<version>-build.<build>/bcut.
On Windows, bin/baocut.ps1 uses the same explicit overrides,
development-checkout build, and PATH lookup first. It then checks cached
<version>-build.<build> CLIs newest-first — by version and build, because
the handshake only reports the marketing version and cannot tell two builds
apart — and compatibility-checks them locally. Only when no compatible cache
exists does it find the newest stable baocut-v<version>-build.<build> GitHub
Release that includes windows-cli-release.json, downloads its x64 Windows
archive, verifies the manifest-pinned SHA-256, and caches bcut.exe under
%LOCALAPPDATA%\BaoCut\cli\<version>-build.<build>\bcut.exe. "Newest" is the
highest <version>/<build> parsed from the release tags, not the first entry
the API returns: Windows assets are appended to an already-published macOS
release, so creation order does not track build order. The Windows
archive is currently an unsigned preview, so SmartScreen, Smart App Control,
or enterprise policy may warn about or block it; SHA-256 proves download
integrity, not publisher identity.
A compatible cache normally ends the search, so a rebuild published under the
same marketing version is not picked up on its own — nothing local announces
it, since the Windows skill ships no CLI pin and --json version carries no
build number. Set BAOCUT_SKILL_CLI_UPDATE_CHECK=1 to let the cache path
compare against the newest release and adopt a higher build; unset, that path
stays entirely offline, and any failed check silently keeps the cached CLI.
BAOCUT_SKILL_NO_DOWNLOAD=1 still wins over this opt-in.
Before choosing a Windows cache or release, the resolver runs
bin/detect-windows-cli-variant.ps1. The detector uses nvidia-smi and selects
cuda13 only when at least one NVIDIA GPU has compute capability 8.0+ (Ampere /
RTX 30 series or newer) and the installed driver is >= 580; a missing or failed
probe and an incompatible GPU select cpu. The CUDA choice additionally
requires backend candle-cuda, gives the cache directory a -cuda13 suffix,
and downloads the release's windows-cli-cuda-release.json and
…-x86_64-pc-windows-msvc-cuda13.zip asset, extracting the bundled CUDA runtime
DLLs next to bcut.exe. No CUDA Toolkit install is needed. If no release ships
the selected CUDA asset yet, the resolver fails clearly instead of silently
using a different build. BAOCUT_VARIANT=cpu|cuda13 remains an explicit force
override for troubleshooting and controlled environments; normal installs do
not need it.
The resolver then checks the CLI contract and minimum BaoCut App version
before it runs the requested command, and finally checks the CLI's
architecture against the host: --json version reports target (and, on
current CLIs, rosetta), and a CLI built for another architecture — typically an
x86_64 bcut on Apple Silicon, which macOS silently runs under Rosetta 2 with
backend: candle-cpu — is refused for auto / transcribe (exit 3) and only
warned about for other commands. Do not work around that refusal by setting
BAOCUT_ALLOW_FOREIGN_ARCH=1 (or the CLI's own BCUT_ALLOW_ROSETTA=1); a
100-second clip once sat 40+ minutes in VAD on such a binary while the native
build finished the whole pipeline in about three. Resolve it by choosing a
native CLI: BaoCut.app's bundled CLI, a native workspace build, or the pinned
release CLI.
If nothing above resolves, or the resolved CLI is older than
metadata.minAppVersion, the resolver downloads the CLI pinned by this
skill's cli-release.json — the standalone release archive built from the
same commit as the matching App. It verifies the archive's SHA-256 against
the pin before extracting anything, unpacks bcut and its co-located
mlx.metallib into the cache, and reruns the full contract and version
handshake against the downloaded binary. Any failure exits 3 with the manual
download URL. The download carries no com.apple.quarantine attribute and the
Developer ID signature lives in the binary itself, so the cached CLI runs
without a Gatekeeper prompt. The resolver exports the packaged Metal library
path before executing the cached CLI, so local MLX transcription never depends
on a metallib left behind on the release build machine.
Two deliberate exceptions never trigger the download: an explicit
BAOCUT_CLI-style override and a development checkout. Both are chosen on
purpose, so a failing handshake there must be fixed at the source — update the
override or rebuild the workspace — rather than silently shadowed by a release
binary. Set BAOCUT_SKILL_NO_DOWNLOAD=1 to disable the download entirely;
BAOCUT_SKILL_NO_DEV=1 disables development-checkout detection.
The skill copy bundled inside BaoCut.app has no cli-release.json, because an
App install always ships its own matching CLI beside it.
If the resolver exits 3, follow its guidance instead of bypassing the check.
Choose the workflow
- For transcription, polish, and translation, create the project in the shared projects library first, start the preview server, then run the pipeline; read references/workflows.md.
- For a complete local pipeline, use
auto; read references/workflows.md. It defaults to the fast path without closing refinement; only pass--refineafter the user chooses quality-first execution. - To run transcription on another machine on the same local network instead of this one, read the remote-node note in references/workflows.md.
- For an Agent-backed AI stage with pending calls, immediately read and follow
references/agent-tasks.md. For a short clip
its "short-job fast path" is the whole procedure (see "Right-size the run"
below). For long media its on-demand worker
rules — pool sized from the actual page plan (translate uses
ceil(source words / 880)by default (--align-fusion rows), or/2200under--align-fusion on|off; align also enforces at most 40 items and a complexity budget, all capped by real slots), per-stage worker tiers (mid-tier for translate/polish, high-reasoning tier for align and repair), hand-written align answers with no scripted cutting and no unchanged resubmits — and its consolidated-repair rules (including whatrefine-align --only-hardreally dispatches) are execution requirements, not optional tuning. - For the Subtitle Studio browser preview — serving and mounting projects,
applying page edits, page requests, history recovery, punctuation display,
or preview troubleshooting — read
references/studio.md. The page code itself is this
skill's
templates/directory, served live byserve. - For source cuts, OUTPUT clip arrangement, appended media, or rough cutting, read references/editing.md.
- For overlays, B-roll, watermarks, text styles, or debug frames, read references/elements.md.
- For overlay motion, read references/animation.md.
- For reusable foreground templates — caption slot, segment rail, progress bar,
station logo — and the
data.jsondata layer that binds them, read references/templates.md. - For text baked into video frames, read references/screentext.md.
- For delivery, run
check --strictand then use the export recipes in references/exports.md. - For granular project edits, discover the installed surface with
specand command--help; do not infer commands from older BaoCut releases. - For deterministic Transcript lookup, replacement, or lexical name fixes,
use the CLI before opening Subtitle Studio: run
transcript find, thentranscript replace --expect <count>. Use--scope allwhen the same text must change in both cue content and speaker display names; usespeakers renamefor an id-based speaker-only rename. Re-read withtranscript findafter the mutation. Do not search or type through the page when the CLI exposes the operation; the browser is for visual review and user-driven interactive edits. Ifspeclackstranscript find/replace, update the CLI instead of silently falling back to DOM editing. - For checking whether this skill or the CLI has a newer release, verifying skill/CLI version consistency, or helping the user update, read references/updates.md.
Optional completion accounting
- Keep stage timing and call accounting disabled by default. Enable it only when the user explicitly requests stage timing, call counts, performance statistics, or a run summary containing them. Do not collect baselines or add an accounting table otherwise.
- When enabled, start a run ledger before the first long or mutating command.
If the project may use
--llm agent, snapshottask status <project> --jsonand retain the existing(task, callId)pairs as the baseline. - Record wall-clock start and finish times for every workflow stage that
actually runs. For
auto, split the ledger at JSONLstagetransitions; keep per-language work distinct (for exampletranslate:zh-Hansandalign:zh-Hans) and include repair, quality-check, and export stages when they run. Mark reused or skipped stages explicitly instead of assigning invented durations. - After the producer's terminal event, read
task statusonce more. DiffcompletedCallsagainst the baseline, group the new accepted calls by their stage/kind, and count repair or retry calls in the stage that caused them. Unless the user defines another meaning, “calls” means new Agent/LLM calls, not shell or CLI invocations. Follow the timing rules in references/agent-tasks.md. - When enabled, end the task with a compact table containing
Stage,Wall time,New calls, andResult, followed by end-to-end wall time and total new calls. Use0for stages that made no Agent/LLM call andunobservedwhen timing evidence is unavailable. Never sum overlappingqueueMs,workerMs, ortotalMsvalues and present the result as elapsed wall time.
Shared projects library and multi-client sync
- New transcription/translation projects belong in the shared projects
library so the BaoCut App sees them immediately. Resolve it with
"$BAOCUT_SKILL_ROOT/bin/baocut" --json project dir(macOS default:~/Library/Application Support/BaoCut/projects); create projects there withproject createunless the user names another location. Projects created in a temporary or scratch directory are not added to the library (they would leave a dead entry once the directory is wiped); the CLI reportsdata.registered: falseand warns. Useproject register <path>only when the user explicitly wants such a project listed. - For URL media, never invent or derive a
--download-dir. Omit the flag unless the user explicitly names a one-off destination; the CLI then honors the shareddownload.dirsetting. When it is absent, the video lands in the user's system download folder (Windows Downloads Known Folder,~/Downloadson macOS and Linux) — never inside the project. - After any URL-media run downloads or reuses a video, read its actual path from
data.mediain atranscriberesult or from--json project show <project>atdata.manifest.media.path. Tell the user that exact path explicitly; do not merely say that the download completed. - Progress is shared state: the App, the browser preview, and other CLI sessions all observe the same project registry and per-project progress files. A transcription started from this skill shows up — with live progress — in the App and at the preview URL; do not duplicate work you can already observe.
- After starting a transcription, always surface the preview URL (see references/workflows.md): open it in the agent's built-in browser to verify, and print it for the user so they can open the same page in their own browser.
Safety and truth sources
- Treat
transcript.jsonwords[]as the persistent text/time truth. Use BaoCut commands or Subtitle Studio apply operations; do not hand-edit word atoms, fingerprints, stage stamps,trans, ortransAlign. - Translation alignment is target-first: freeze natural target-language display pieces before mapping them to consecutive sentence-word spans. Never copy, infer, or preserve original subtitle cue boundaries for this purpose; the local Agent and Cloud Model follow the same contract.
- Treat
timeline.jsonas command-owned truth. Source-local cuts and OUTPUT clips are separate layers; overlays live on OUTPUT time. Do not hand-edit the timeline, AI provenance, revisions, or fingerprints. - Preserve input media. A normal pipeline writes into a
.bcutproject and does not modify the source file. Feed the original container directly;transcribedecodes and resamples it itself, so extracting a WAV first only repeats work the command already does. - Prefer
--jsonfor short commands and--jsonlfor long commands. JSONL cancellation is one stdin line:{"cmd":"cancel"}. - AI
--reviewoutput is only a candidate. Inspect it, then explicitly runreview acceptorreview reject. - A successful polish is not the end of a named multi-speaker task while
placeholder labels remain. After accepting any polish review, follow
the confirmed-speaker sync:
apply only evidence-backed identities with
speakers rename, preserve ambiguous labels, and report every unresolved speaker id. - Run
check --strictbefore claiming a deliverable is ready. Exit 2 means the quality gate found unresolved work; exit 3 means a compatibility or worker handoff condition. - Treat
source-language-mismatch,target-language-mismatch,translation-placeholder,translation-source-copy, andtranslation-duplicate-collapseas hard failures. Follow the returned sentence-scoped fix command; do not bypass the validator or reuse an older task response manually. - Re-read state after every edit. Exit 0 proves the mutation committed, not that
its visual timing or composition is correct; use list commands and
frames,broll preview, oranimation previewas appropriate.
Capability preflight
"$BAOCUT_SKILL_ROOT/bin/baocut" --json spec
"$BAOCUT_SKILL_ROOT/bin/baocut" doctor --quick --json
Complete the mandatory startup version gate before running this preflight.
Do not treat a missing ffmpeg/ffprobe in the doctor report as a blocker and
do not preinstall them. They are on-demand, task-level dependencies: common
workflows (transcription, waveforms, single continuous main-media export) run
without them, and the tasks that do need them (URL download merging, complex
timeline flattening, BCF video encoding) fail at the point of use with a clear
error — install only when such a task actually asks for it.
In a development checkout, long local transcribe and auto commands require
an optimized CLI. When only a debug build is current, the resolver runs
scripts/dev/prepare-bcut.sh before continuing instead of silently accepting
roughly 2x slower inference. Weigh that against the media length: a release
build of the workspace costs many minutes, while debug inference on a clip
under about 15 minutes costs seconds to a few minutes more than release — so
for such a short clip, when only a native debug build is current, export
BAOCUT_ALLOW_DEBUG_INFERENCE=1 and run it rather than compiling first. Let
the resolver prepare the release CLI for long media, and keep the flag off for
anything else. For an Agent-backed AI pipeline, pass
--llm agent explicitly; this prevents a stale BCUT_LLM_DEFAULT from
silently selecting a provider that has no usable key.
Right-size the run
Decide the shape of the run from the media length before starting anything,
and keep the shape fixed. For a media file or URL, yt-dlp --print duration_string / ffprobe or project show tells you the duration up front.
- Short clip (under ~15 minutes, transcript on one page — up to ~2200 source
words): the fast Agent-backed pipeline is a fixed serial chain of five to six
calls —
analysis→polish→translate-brief→translate→align-edges, plusalign-rewriteonly if a chunk is over the hard width; closing refinement is not part of the default run. Every call has exactly one pending item, so there is nothing to parallelize: answer them yourself in the orchestrating session, one after another, claim → read contract and payload in the same step → write →submit --next. Do not start worker subagents, do not spawn a task-tracker of seven pipeline steps, and do not read the fleet-sizing rules of references/agent-tasks.md as instructions for this case — its "short-job fast path" section is what applies. Two settings are part of this shape, not optional tuning: exportBCUT_LLM_MAX_WORKERS=1before startingauto, so the engine plans one polish page for the whole transcript instead of splitting it across the default three worker slots (a 1500-word clip otherwise dispatches three ~600-word polish pages plus aseam-repair, and every extra page waits in the queue while you answer the previous one); and watch the JSONL only for"event":"(batch-dispatch|error|done)"— a filter that also matchestranscribestage lines floods the monitor with one event per recognized segment. Expected wall clock on native hardware: transcription of a 2-minute clip finishes within about 3 minutes including model checks, and each AI call takes about one minute of your own answering (the singletranslatepage of an 8–10 minute clip is the largest, several minutes); the whole task should be over in roughly 10 minutes with under 40 tool calls. - Long media (a talk, a lecture): follow the on-demand worker rules in
references/agent-tasks.md — pool size from the
workerPlan, tiers per stage,--nextchaining.
Whatever the size, watch the JSONL event stream through one Monitor (or
one background tail) rather than polling, and apply a stall budget: a
phase:"model-wait" event is an explicit, cancellable wait for another model
download or repair, not a silent stall; keep watching until it advances or
cancel the run if that model work is no longer wanted. Otherwise, on a
short clip, no new progress event for 3 minutes during transcribe means
something is wrong — check --json version (target, backend, rosetta),
ps for the process's CPU time, and the project's progress file — do not
wait for a 20-minute monitor timeout. Read the JSONL's event:"done" (or an
error event) as the terminal signal: after it, do not task claim again;
run check --strict, project show, and the preview verification. In fast
mode, summarize data.refineOffer[], state the optional refinement's benefit
and cost, and ask whether the user wants it; do not start it without a new
affirmative answer.
When the resolver reports a version or handshake problem, follow references/updates.md and do not bypass the refreshed CLI handshake.
Use spec as the machine-readable source of supported commands and flags. Keep
project paths quoted and use BCP-47 language tags such as zh-Hans, en, or
ja. This skill requires CLI spec >=1.31,<2.0; if a recipe and spec differ,
stop and follow the compatibility error rather than guessing.
Signals
- GitHub stars
- 491
- Forks
- 28
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
baocut- Source
- github.com/jimliu/baocut