@veedstudio/openedit-cli
v0.0.19
Published
Open Edit command-line tool
Keywords
Readme
@veedstudio/openedit-cli
The Open Edit command-line tool: agent-driven video creation and editing, powered by VEED. This package is being migrated in from the Open Edit repository incrementally, so early versions expose only part of the eventual command surface.
Usage
npx @veedstudio/openedit-cli --helpCommands
login
Log in with VEED (OAuth 2.1 + PKCE via the browser; the token is stored locally and refreshed automatically):
npx @veedstudio/openedit-cli loginPass --manual (or set VEED_LOGIN_MANUAL=1) when no reachable browser exists:
the URL is printed, and the redirect is pasted back instead of caught on a
localhost loopback.
token
Print a valid VEED access token for other tools to consume, refreshing it
first when stale (VEED_ACCESS_TOKEN, when set, is passed through as-is):
npx @veedstudio/openedit-cli tokenExits non-zero when no login is stored. --path prints the token store
location instead of a token.
transcribe
Transcribe videos, writing runs/<key>/transcript.json. Locally with WhisperX
(the default — free, offline):
npx @veedstudio/openedit-cli transcribe video.mp4 [...] [--model medium] [--language de] [--force]A transcript already on disk is left alone (it may have been retimed onto an
edit); --force transcribes it again.
Or hosted by VEED (premium quality; requires the one-time login, and spends
the workspace's VEED transcription credits — --workspace <id> names which,
required only when the account has several):
npx @veedstudio/openedit-cli transcribe --provider veed video.mp4 [...]--record <veed|whisperx|custom> [--model <id>] records the transcription
provider choice in .open-edit-prefs.json instead of running anything.
whisper
Map a Whisper-family JSON produced by your own service (WhisperX,
openai-whisper, whisper-timestamped, mlx-whisper, whisper.cpp -oj -ml 1, or
the OpenAI API's verbose_json with word granularity) into the same
runs/<key>/transcript.json:
npx @veedstudio/openedit-cli whisper transcription.json media.mp4 [...] [--force]Word timestamps are required; the media argument may be a video or an audio file.
prep
Probe the source canvas, synthesize word-timings.json from the transcript's
real per-word times, and cut one base frame per beat (the transcript must
already exist):
npx @veedstudio/openedit-cli prep video.mp4 [...]synth-timings
Even-split word reveal delays for a single beat window:
npx @veedstudio/openedit-cli synth-timings --start 1.2 --end 3.4 --words "A B C" [--out file.json]generate / generate-set / sample-presenter
Fabric generation — source footage from a script, when there is no video to
caption. Generation spends real credits, so it is two commands: the first
quotes the cost and records the approval, the second spends exactly what was
approved (no --script on the spend pass — the recorded, hashed script is what
bills):
npx @veedstudio/openedit-cli generate --script "spoken words" --key my-run --workspace <id>
npx @veedstudio/openedit-cli generate --key my-run --yes--resume collects a job already created and paid for; --abandon <sessionId>
clears one abandoned charge record. generate-set --shots shots.json covers
several shots under one approval, and sample-presenter proposes a
deterministic character/voice pair for a run key (listing costs nothing).
background-removal / lipsync
Remove a video's background (VEED's free route by default; --fast uses a fal
model billed to your own fal key), or re-lipsync a video to a new audio track
(always fal-billed). Both use the VEED login only to host the local file:
npx @veedstudio/openedit-cli background-removal video.mp4 [--fast] [--mask-only] [--out <path>]
npx @veedstudio/openedit-cli lipsync video.mp4 narration.mp3 [--out <path>]The fal key comes from FAL_KEY, or OPEN_EDIT_FAL_KEY_FILE pointing at a
file that holds it.
install-engine
Download the veed render engine (checksum-verified, from its public GitHub releases) into the app-data dir, or upgrade an existing install:
npx @veedstudio/openedit-cli install-engine [weave-v<semver>]VEED_ENGINE_BIN overrides where the engine is looked for. The binary is
licensed separately (PolyForm Shield); its license installs beside it.
install-ffmpeg / install-whisperx
The other two installers. install-ffmpeg checks for a working FFmpeg first
(VEED_ENGINE_FFMPEG, then PATH, then a previous install) and only downloads
when nothing works — a checksum-verified static build into the app-data dir
(the download route is Windows-only; macOS points at brew install ffmpeg).
install-whisperx installs the local transcription provider into an isolated
uv/pipx tool environment; it never touches the system Python.
npx @veedstudio/openedit-cli install-ffmpeg [--check|--force]
npx @veedstudio/openedit-cli install-whisperx [<version>]mux-audio / mix-audio
Put sound on a render. mux-audio lays a run's source audio (or --audio
<file>) onto its silent render, levelled to -14 LUFS / -1 dBTP (--no-loudnorm
keeps the source level; the line it prints says which correction ran);
mix-audio first builds one track from many pieces — narration, music,
effects — per the run's mix spec, with music ducked under the voice:
npx @veedstudio/openedit-cli mix-audio runs/<key> # → runs/<key>/audio/mix.m4a
npx @veedstudio/openedit-cli mux-audio runs/<key> --audio runs/<key>/audio/mix.m4awcag-pass
Contrast-audit a rendered run through the engine's bundled analyzer, and (with
--apply) promote the remediated template after re-verifying it:
npx @veedstudio/openedit-cli wcag-pass --run runs/<key> [--apply]Needs the installed engine (install-engine). WCAG_REMEDIATE can point at a
replacement remediation applier; by default the bundled one runs as its own
plain-node process.
gates / expect-windows
The whole gate chain — design → lint → verify → wcag → record → probe → mux — as one command over a run directory (run it outside any sandbox; rendering needs a real desktop session):
npx @veedstudio/openedit-cli gates runs/<key> [--doc <subdir>] [--audio <file>] [--no-loudnorm]expect-windows derives the verify.expect timing assertions from a
document's own gates (--write stamps them into the manifest); the chain runs
it automatically. During the migration the design, lint and probe gates still
run from the Open Edit runtime the command is invoked in.
Editing and QA tools
The remaining pipeline tools, each a direct port of its script:
npx @veedstudio/openedit-cli concat-chapters <run-dir> --doc chapters/act-1 --doc chapters/act-2
npx @veedstudio/openedit-cli concat-videos [--canvas WxH] [--fit letterbox|crop|open] <out> <in1> <in2> [...]
npx @veedstudio/openedit-cli cut-frames <video> [--json] # frames at every shot boundary
npx @veedstudio/openedit-cli scene-frames <video> <outDir> # stills for a clip with no beats
npx @veedstudio/openedit-cli scoped-edit <baseline.wv> <candidate.wv> [--allow <selector>]...
npx @veedstudio/openedit-cli brand --file <brand.json> [--brief] [--check]
npx @veedstudio/openedit-cli creative-log --for <video> [--reject "…" --why "…"] [--brief]The cut tools, for an edit made before captioning: measure where speech starts,
stops and pauses; assemble the kept ranges of an EDL (edit decision list) in one
encode with crossfaded joins, each range snapped to the frame grid; and move the
per-word timings you already have onto that timeline instead of transcribing the
cut again. --gap and --crossfade are milliseconds; the EDL is seconds.
npx @veedstudio/openedit-cli speech-probe <video> [--range a:b] [--gap 250] [--window 10] [--json]
npx @veedstudio/openedit-cli apply-edl --edl edl.json --out cut.mp4 [--crossfade 40] [--crf 20]
npx @veedstudio/openedit-cli retime-transcript --edl edl.json --out <OPEN_EDIT_ROOT>/runs/cut/transcript.jsonThe retimed transcript goes where prep reads, runs/<key>/ under the runtime
root, so prep cut.mp4 finds it and the cut is never transcribed.
stills / preview
stills fetches licensed pictures from Wikimedia Commons, recording each
file's terms beside it (search / show / save). preview serves a
read-only localhost page for a run — scrub the footage, follow the transcript,
and the player swaps to the new render when it lands:
npx @veedstudio/openedit-cli stills search "berlin skyline" --limit 10
npx @veedstudio/openedit-cli preview runs/<key>init / readiness
init is the workspace setup: it checks the machine dependencies (git, Node,
pnpm, ffmpeg), clones the Open Edit runtime when the workspace isn't already a
checkout, installs its pinned dependencies, and verifies the render engine.
Bare init applies only safe, workspace-local setup; --dry reports without
writing; --auto-approve also applies machine-global installs and clean
updates, and is only for after a person has approved every reported action.
Exit 10 means something is awaiting that approval; on success the workspace
root is printed on stdout.
npx @veedstudio/openedit-cli init --dry --workspace <dir>
npx @veedstudio/openedit-cli init --workspace <dir>readiness reports what is present vs missing for a run — read-only, no
network — and exits 1 when a blocking item is missing.
Configuration
| Environment variable | Effect |
| --- | --- |
| VEED_ORIGIN | Overrides the default https://www.veed.io origin. |
| OPENEDIT_STATE_DIR | Overrides where login state is stored. |
| OPEN_EDIT_ROOT | The runtime root where runs/<key>/ outputs and .open-edit-prefs.json live (default: the working directory). |
| VEED_ENGINE_FFMPEG / VEED_ENGINE_FFPROBE | ffmpeg/ffprobe binaries (default: PATH; ffprobe defaults beside a configured ffmpeg). |
| WHISPERX_BIN / WHISPERX_MODEL | WhisperX binary and fallback model tier (defaults: whisperx on PATH, small.en). |
| OPEN_EDIT_WHISPERX_DEVICE / OPEN_EDIT_WHISPERX_COMPUTE | WhisperX device/compute (defaults: cpu/int8). |
Login state lives in the platform's per-user app-data directory:
~/Library/Application Support/veed-openedit on macOS, %APPDATA%\veed-openedit
on Windows, and $XDG_CONFIG_HOME/veed-openedit (default ~/.config/veed-openedit)
on Linux.
License
Apache-2.0. See the bundled LICENSE and NOTICE files.
