Record Demo
libnativeapi/nativeapi
Record a demo video of a desktop app — launch it, play a scripted scenario with smooth synthetic mouse input, and capture the screen (cursor and click highlights included) straight to an…
Test convt conversions end to end through the convt CLI, the engines in convt-engines, routing in convt-core, and the Linux file-manager menus in integrations/linux.
$ npx skills add opencoredev/convt --skill test-convt-cli -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install opencoredev/convt test-convt-cli --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/opencoredev/convt.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/test-convt-cli .claude/skills/test-convt-cli && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "test-convt-cli" agent skill from https://github.com/opencoredev/convt/tree/main/.agents/skills/test-convt-cli into .claude/skills/test-convt-cli/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-convt-cli", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/opencoredev/convt/tree/main/.agents/skills/test-convt-cliType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add opencoredev/convt --skill test-convt-cli -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install opencoredev/convt test-convt-cli --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/opencoredev/convt.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/test-convt-cli .agents/skills/test-convt-cli && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "test-convt-cli" agent skill from https://github.com/opencoredev/convt/tree/main/.agents/skills/test-convt-cli into .agents/skills/test-convt-cli/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-convt-cli", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add opencoredev/convt --skill test-convt-cli -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install opencoredev/convt test-convt-cli --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/opencoredev/convt.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/test-convt-cli .cursor/skills/test-convt-cli && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "test-convt-cli" agent skill from https://github.com/opencoredev/convt/tree/main/.agents/skills/test-convt-cli into .cursor/skills/test-convt-cli/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-convt-cli", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/opencoredev/convt.git --path .agents/skills/test-convt-cli--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add opencoredev/convt --skill test-convt-cli -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install opencoredev/convt test-convt-cli --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/opencoredev/convt.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/test-convt-cli .gemini/skills/test-convt-cli && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "test-convt-cli" agent skill from https://github.com/opencoredev/convt/tree/main/.agents/skills/test-convt-cli into .gemini/skills/test-convt-cli/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-convt-cli", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install opencoredev/convt test-convt-cliInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add opencoredev/convt --skill test-convt-cli -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/opencoredev/convt.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/test-convt-cli .github/skills/test-convt-cli && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "test-convt-cli" agent skill from https://github.com/opencoredev/convt/tree/main/.agents/skills/test-convt-cli into .github/skills/test-convt-cli/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-convt-cli", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add opencoredev/convt --skill test-convt-cli -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install opencoredev/convt test-convt-cli --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/opencoredev/convt.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/test-convt-cli .opencode/skills/test-convt-cli && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "test-convt-cli" agent skill from https://github.com/opencoredev/convt/tree/main/.agents/skills/test-convt-cli into .opencode/skills/test-convt-cli/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-convt-cli", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
test-convt-cliTest convt conversions end to end through the convt CLI, the engines in convt-engines, routing in convt-core, and the Linux file-manager menus in integrations/linux.
Test Convt CLI is an agent skill from opencoredev/convt. Test convt conversions end to end through the convt CLI, the engines in convt-engines, routing in convt-core, and the Linux file-manager menus in integrations/linux. Use when changing an engine, a format, the registry, the CLI, or install.py, or when asked to reproduce a conversion bug or prove a conversion works.
Its SKILL.md is about 7.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including scripts (for example `agents/openai.yaml` and `scripts/fixtures.sh`).
It sits in Media & Creative. It works with Linux, LibreOffice and FFmpeg. The repository describes itself as: Convert any file with a right-click. The licence is AGPL-3.0.
Read from SKILL.md and the folder at commit 9214ba0. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/ (Shell), which the agent can run.
Shell commands in SKILL.md call:
buncargopython3bashapt-getshffprobeffmpegFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
CONVT_UPDATE_SIGNING_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Test Convt CLI loads about 7.7k tokens when it runs. Until then it costs about 83 tokens; SKILL.md has 3,453 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from opencoredev/convt at commit 9214ba0, republished under its AGPL-3.0 licence (© opencoredev). 3,453 words, ~7,748 tokens.
.claude/skills/test-convt-cli/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.The CLI is the fastest way to prove engine and routing behavior. The desktop app, the Finder extension and the Linux menus all call the same convt_engines::default_registry(), so a CLI result is the ground truth for what a conversion produces.
Run from the repository root before trusting a result. Read only.
cargo locate-project --workspace --message-format plain # must be this checkout's Cargo.toml
cargo build -p convt-cli && ./target/debug/convt enginesconvt engines prints each ready engine (image, svg, libheif, ffmpeg, pdfium, libreoffice) and each unavailable one with its reason. A conversion that fails with "no route" usually means an engine is missing here, not a routing bug. Fix the environment first:
pdfium unavailable: bash scripts/fetch-pdfium.sh (writes vendor/pdfium, gitignored).ffmpeg or libreoffice unavailable: install the package, or point CONVT_FFMPEG / CONVT_SOFFICE at a binary. See crates/convt-engines/src/lib.rs for discovery order.Always run ./target/debug/convt from this checkout. A convt on PATH may be an older install.
Use synthetic inputs in a fresh temporary directory, never files from a user's home.
work=$(mktemp -d /tmp/convt-test.XXXXXX)
bash .agents/skills/test-convt-cli/scripts/fixtures.sh "$work/in"This writes sample.png, sample.mp4 (3 s, video and audio), sample.wav, sample.svg, sample.txt, and sample.pdf when LibreOffice is present. Add new fixtures to that script rather than committing binaries.
Write outputs to a separate directory with -o so a same-format or failed run cannot touch the inputs.
c=./target/debug/convt; mkdir -p "$work/out"
$c targets "$work/in/sample.mp4" # what the menus would offer
$c "$work/in/sample.mp4" --to webm -o "$work/out"
$c "$work/in/sample.png" --to avif -o "$work/out"
$c "$work/in/sample.svg" --to jpeg -o "$work/out"
$c "$work/in/sample.pdf" --to png -o "$work/out" # one file per page: sample.png, sample-2.png, ...Options, presets and batches:
$c "$work/in/sample.png" --to jpeg -q 60 --max-size 64 -o "$work/out"
# Transparent areas: white by default for JPEG and PPM, or --background black,
# "#ff8800" or transparent (refused for formats that can't store it).
$c "$work/in/sample.png" --to jpeg --background black -o "$work/out"
$c "$work/in/sample.pdf" --to webp --pages 2- --dpi 72 -o "$work/out" # named by page: sample-2.webp, ...
$c "$work/in/sample.mp4" --to mp4 --video-height 120 -o "$work/out"
export CONVT_CONFIG_DIR="$work/cfg" # never the user's real presets
mkdir -p "$CONVT_CONFIG_DIR/presets"
printf 'to = "jpeg"\nquality = 60\n' > "$CONVT_CONFIG_DIR/presets/thumb.toml"
$c presets && $c "$work/in/sample.png" --preset thumb -o "$work/out"
$c "$work/in" -r --to webp -j 2 --json -o "$work/batch" # subfolders mirrored under -o--json prints one event per line on stdout (started, progress, done, failed with a kind, then summary). Folder files that can't reach the target, or already are it, are skipped quietly; files named directly report their errors. Exit codes: 0 all done, 1 any failure, 130 cancelled.
To test cancellation, start a conversion of a long video in the background, kill -INT that PID (never pkill), and check that it exits 130, that its FFmpeg child is gone (ps -o pid= --ppid <pid> before the kill), and that the output directory holds no .convt-* staging folder or partial file.
HEIC and AVIF decode through the patched libheif (libheif.so.1, or CONVT_LIBHEIF_DIR). Unpatched system libraries are unavailable because they cannot disable implicit plugin loading. For full host verification, select the built bundle with absolute CONVT_LIBHEIF_DIR and CONVT_LIBHEIF_PLUGIN_DIR, and prepend its lib directory to LD_LIBRARY_PATH. Set CONVT_FFMPEG and CONVT_FFPROBE to the bundle tools so the independent AVIF validator has container support. The Python fixture helper separately needs a trusted absolute LIBHEIF_PLUGIN_PATH; the engine ignores that variable. The matrix generates its own HEIC with alpha. It first tries a libheif HEVC encoder, then uses FFmpeg's libx265 to encode the color and alpha items in a small HEIF container. It generates AVIF with libheif's AV1 encoder, independently of convt's AVIF encoder. When no HEIC encoder is available, CONVT_TEST_HEIC=/path/to/sample.heic opts into a local sample, copied into the temporary fixture directory and compared against separately decoded source pixels. No real sample belongs in the repository.
Pick the paths your change touches. For a routing change, also check that targets does not offer something it should not. A still image must never list a video or audio format through a multi-hop route; crates/convt-core/src/registry.rs has tests for this.
Builds from source skip the license check, so convert works without a key. To try the trial and activation flow, make a development key pair and opt in at run time. Always set CONVT_LICENSE_STORE=file: without it a key goes to the user's real Secret Service keyring.
cargo run -p convt-license --example dev-keys -- keygen # writes .convt-dev/ (gitignored)
key=$(cargo run -q -p convt-license --example dev-keys -- issue you@example.com 2027-10-02)
export CONVT_CONFIG_DIR="$work/cfg" CONVT_DATA_DIR="$work/data" CONVT_LICENSE_STORE=file
export CONVT_LICENSE_ENFORCE=1 CONVT_LICENSE_PUBKEY=$(cat .convt-dev/license.pub)
$c license # Free trial: 7 days, starting with ...
$c "$work/in/sample.png" --to jpeg -o "$work/out" # starts the trial: $work/data/trial
echo 2026-01-01 > "$work/data/trial"; $c "$work/in/sample.png" --to jpeg -o "$work/out" # trial ended, exit 1
echo "$key" | $c license activate && $c license # key in $work/cfg/license.key, mode 0600
$c license removeformats, targets, engines and presets never need a license; only conversions do. A key issued with an updates_until before today's build date shows the "newer than your license covers" message. Delete .convt-dev when done unless you need the key again, and never commit it.
The Secret Service path has one ignored test. Run it only on a private bus with its own runtime and data directories, so it can't reach the user's keyring:
T=$(mktemp -d); mkdir -m 700 "$T/run"; mkdir "$T/data"
env -u DBUS_SESSION_BUS_ADDRESS XDG_RUNTIME_DIR="$T/run" XDG_DATA_HOME="$T/data" dbus-run-session -- sh -c \
'echo -n test | gnome-keyring-daemon --unlock --components=secrets >/dev/null; cargo test -p convt-license --features client -- --ignored secret_service'
rm -rf "$T"The Keychain on macOS and Credential Manager on Windows have no test path here; report them as unverified.
A zero exit code and a -> path line are not enough. Inspect the output:
ffprobe -v error -show_entries stream=codec_name,width,height:format=duration -of compact "$work/out/sample.webm"
file "$work/out/"*Check codec, dimensions, duration, and page count against what the change should produce. For images, open the file with the Read tool to look at it. Report which engines were unavailable, because those routes were not exercised.
Format entries run convt-app open --to <format> -- <files>, so the app shows progress and errors. Every supported Linux menu also has “More options…” which runs convt-app open -- <files> to open Quick convert without choosing a target. install.py reads convt formats --json and convt targets to build them, and also installs convt-app.desktop (Open with, and the convt:// handler). It needs both binaries on PATH.
Start with the unit tests. They run each generated command the way the file manager would: Dolphin entries and convt-app.desktop through gio launch, Thunar through sh -c, Nemo through GLib's argv parser, and the Nautilus extension against stubbed GObject classes. A fake app in a folder with spaces and quotes records its arguments, and the file names include quotes, $HOME, a backtick, 100% and a leading dash.
python3 -m unittest discover -s integrations/linuxTests that need GLib, gio or desktop-file-validate skip without them; say which ran. Then check the real output against a throwaway home, since install.py writes into $HOME and runs xdg-mime:
cargo build -p convt-cli && cargo build -p convt-app # see test-convt-desktop for the app's build needs
h="$work/home"
HOME="$h" XDG_DATA_HOME="$h/.local/share" XDG_CONFIG_HOME="$h/.config" PATH="$PWD/target/debug:$PATH" \
python3 integrations/linux/install.py --dolphin --nemo --thunar --nautilus
find "$h" -type f | head
desktop-file-validate "$h/.local/share/applications/convt-app.desktop"Check that each Exec/command points at target/debug/convt-app, that Dolphin .desktop files are mode 0755, and that uca.xml parses (python3 -c 'import xml.dom.minidom,sys;xml.dom.minidom.parse(sys.argv[1])' "$h/.config/Thunar/uca.xml"). The unit tests emulate Nemo and Thunar from their source and Dolphin through GIO; none of them runs inside the real file manager. Seeing the menu in Dolphin, Nemo, Thunar or Nautilus means launching the file manager, which needs the user's explicit permission in the current request. Without it, report the menus as verified by emulation only. With it, use the recipe below on a private display, never the user's desktop session.
What each menu looks like in the real app, so you can tell a regression from the expected shape:
convt targets order, then "More options…". A video's 23 targets run past a 900 pixel screen; the popover scrolls.convt-zz-more-options.nemo_action. Nemo compares file names byte by byte. Nemo 6.0 has no action layout file, so a submenu is not possible there.convert_<target> and options, which puts "More options…" last.Nautilus 46 and Thunar are installed system-wide here; Nemo, Dolphin and nautilus-python are not, and there is no passwordless sudo. Install them into a throwaway prefix instead. apt-get -s install works without root and lists exactly the packages this machine is missing:
REPO=$PWD W=$(mktemp -d /tmp/convt-fm.XXXXXX); cd "$W"; mkdir debs root bin home
for p in nemo dolphin python3-nautilus; do apt-get -s install $p | awk '/^Inst /{print $2}'; done | sort -u > all.txt
(cd debs && apt-get download $(cat ../all.txt)) # about 250 packages, 57 MB
for d in debs/*.deb; do dpkg -x "$d" root; done # about 270 MB
ln -s "$REPO/target/debug/convt" bin/convt; ln -s "$REPO/target/debug/convt-app" bin/convt-appPackage postinst scripts never run, so do their work by hand. Nemo needs its schemas compiled together with the system ones: copy /usr/share/glib-2.0/schemas/*.xml and *.override plus root/usr/share/glib-2.0/schemas/* into $W/schemas and run glib-compile-schemas $W/schemas. Dolphin needs kbuildsycoca5 run once with its environment set (below).
Nautilus loads extensions only from the directory compiled into the binary, /usr/lib/x86_64-linux-gnu/nautilus/extensions-4; no environment variable changes it. Copy /usr/bin/nautilus to $W/bin/nautilus and overwrite that string with a shorter private path padded with NUL bytes, then put libnautilus-python.so from root/usr/lib/x86_64-linux-gnu/nautilus/extensions-4 in that directory:
mkdir "$W/nx"; cp root/usr/lib/x86_64-linux-gnu/nautilus/extensions-4/libnautilus-python.so "$W/nx/"
python3 - "$W" <<'EOF'
import sys
old = b"/usr/lib/x86_64-linux-gnu/nautilus/extensions-4\0"; new = sys.argv[1].encode() + b"/nx"
data = open("/usr/bin/nautilus", "rb").read()
assert data.count(old) == 1 and len(new) < len(old)
open(sys.argv[1] + "/bin/nautilus", "wb").write(data.replace(old, new + b"\0" * (len(old) - len(new))))
EOF
chmod +x "$W/bin/nautilus"nautilus-python reads Python extensions from $XDG_DATA_HOME/nautilus-python/extensions, which install.py --nautilus fills in the private home.
Export the private home first, then start Xvfb, a private D-Bus bus and fake-portal.py as in test-convt-desktop (Launch headless on Linux), with $W as the work directory. The order matters: services the bus starts on demand (dconf-service, gvfsd-metadata, tracker-miner-fs, goa-daemon) inherit the bus daemon's environment, not the file manager's. A bus started with the real HOME writes Nemo and Nautilus settings into the user's real ~/.config/dconf/user and rewrites ~/.cache/tracker3, even though every file manager has a private home. Then run install.py --nautilus --nemo --dolphin in that environment:
export HOME=$W/home XDG_DATA_HOME=$W/home/.local/share XDG_CONFIG_HOME=$W/home/.config XDG_CACHE_HOME=$W/home/.cache
export XDG_RUNTIME_DIR=$W/run CONVT_RUNTIME_DIR=$W/run CONVT_CONFIG_DIR=$W/cfg CONVT_DATA_DIR=$W/data CONVT_LICENSE_STORE=file
export PATH=$W/bin:/usr/bin:/bin NO_AT_BRIDGE=1
# Now start Xvfb, dbus-daemon and fake-portal.py, then:
python3 "$REPO/integrations/linux/install.py" --nautilus --nemo --dolphin
R=$W/root L=$R/usr/lib/x86_64-linux-gnu
GI_TYPELIB_PATH=$L/girepository-1.0 nautilus "$HOME/Samples" &
LD_LIBRARY_PATH=$L XDG_DATA_DIRS=$R/usr/share:/usr/share GSETTINGS_SCHEMA_DIR=$W/schemas $R/usr/bin/nemo "$HOME/Samples" &
LD_LIBRARY_PATH=$L QT_PLUGIN_PATH=$L/qt5/plugins QML2_IMPORT_PATH=$L/qt5/qml QT_QPA_PLATFORM=xcb \
XDG_DATA_DIRS=$R/usr/share:/usr/share XDG_CONFIG_DIRS=$R/etc/xdg:/etc/xdg PATH=$W/bin:$R/usr/bin:/usr/bin:/bin \
sh -c 'kbuildsycoca5 >/dev/null 2>&1; exec dolphin "$HOME/Samples"' &Run one file manager at a time so their windows don't overlap. Nautilus forks, so $! is not its PID, and each one starts helpers on the private bus (gvfsd, dconf-service, tracker-miner-fs, goa-daemon and others). Find all of them by their environment and kill only those:
bus=$DBUS_SESSION_BUS_ADDRESS
for d in /proc/[0-9]*; do { tr '\0' '\n' < $d/environ; } 2>/dev/null | grep -qxF "DBUS_SESSION_BUS_ADDRESS=$bus" && echo ${d#/proc/}; doneDolphin shows blank file icons because no Breeze icon theme is installed; thumbnails and menus work. Drive the menus with xdotool (right-click, then click "Convert with convt"; Qt submenus open on click more reliably than on hover) and capture with ffmpeg -f x11grab. To keep icon positions stable between conversions, move each output out of the folder after checking it. A target click converts silently next to the original; "More options…" opens Quick convert, which stays hidden but alive after Cancel, so later requests reuse the same convt-app process.
Before and after, checksum the real home's .local/share/{nemo,kio,nautilus-python,applications,mime,gvfs-metadata}, .config/{Thunar,nemo,dconf,mimeapps.list} and .cache/tracker3, and compare. A changed .config/dconf/user means the bus was started with the real home. When done, kill the PIDs found above, then rm -rf "$W". The work directory ends up about 350 MB.
Run both tiers from the repository root with the file-backed license store. Plain Cargo tests include a real declared conversion for every available engine, an encoder regression for RGB ICO and floating-point EXR inputs, a 16-bit precision check, routing checks, and CLI scenarios. The CLI tests cover recursive folders, parallel jobs, JSON progress, presets, output directories, collisions, selected PDF pages, corrupt and unsupported inputs, and a read-only destination. Engines or validator tools that are missing are reported as skips. Running as root cannot prove the Unix permission check, so that test reports the limitation.
export PATH=$HOME/.cargo/bin:$HOME/.bun/bin:$PATH CONVT_LICENSE_STORE=file
cargo test
# Release binaries use only explicit, executable-adjacent and system library paths.
export CONVT_PDFIUM_DIR="$PWD/vendor/pdfium/lib"
cargo test --release -p convt-engines
bun run rs:check
python3 -m unittest discover -s integrations/linux -vPDFium's repository vendor directory is discovered automatically only in debug builds. Release tests must set CONVT_PDFIUM_DIR before launching the test process, as shown above, or use bash scripts/test-engines.sh --release. The matrix package command uses that launcher, which supplies the repository library path unless an explicit override is already set. It does not change shipped discovery.
The full tier is explicit. It generates one tiny fixture per format ID, reads every offered target from the registry, converts each pair, and validates the result. Fixtures are shared across cases. The default is eight concurrent workers; each LibreOffice process gets a private profile. Tests use temporary directories and remove their outputs after the run.
bun run test:matrix
CONVT_MATRIX_INPUT=heic,avif bun run test:matrix
CONVT_MATRIX_TARGET=pdf,png bun run test:matrix
CONVT_MATRIX_JOBS=16 bun run test:matrix
bash scripts/test-engines.sh --release --test matrix full_matrix -- --ignored --nocaptureInput and target filters accept comma-separated format IDs. An empty selection fails instead of reporting success. CONVT_MATRIX_REPORT=/tmp/convt-matrix.json saves case results, timings and failure reasons as JSON. CONVT_MATRIX_KEEP=1 retains the temporary directory and prints its path for diagnosis. Remove only that printed directory when finished.
The matrix checks image magic, dimensions, quadrant colors and alpha; media containers, codecs, streams, duration, changing first and last video frames and the 440 Hz audio tone; document marker text; presentation slide count and text; and spreadsheet cells A1, B1, A2 and B2. PDFium extracts PDF text. Office images are compared with an independently exported and rendered reference PDF. The two-page PDF fixture has distinct colored page markers and a large black text block. Its text region must contain the expected dark pixels; a regression test erases the text while preserving the colored markers and proves that validation fails. Output names and selected-page behavior are checked too. Video height is a maximum and never enlarges the source; scaled dimensions stay even. ICO's maximum size of 256 pixels, SVG's 96 DPI user units, binary GIF transparency, and bounded media encoder padding are accounted for explicitly.
The summary prints pass, failure and skip counts per input category, the slowest cases, every failure reason, and wall time. An explicit required-route table is checked independently of the offered-target loop. It covers every engine step family and the HTML, RGB ICO, AVIF and PDF regressions; removing a required route fails when its backend capability is available. Known intentional gaps, including raster-to-SVG, are reported separately. HEIC output is capability-gated and required when a HEVC encoder is available. The HEIC suite also checks linear-gamma PNG NCLX, custom primaries, white adaptation, plugin-path constructor sentinels, 10-bit capability and explicit 8-bit fallback. See docs/heic.md for format notes. Raster-to-HEIC validation skips when Python or the independent HEVC decoder is missing. Libheif advertises HEIC and AVIF input steps only when the matching HEVC or AV1 decoder plugin is available, and unavailable input decoders are skipped explicitly. The format table currently has 40 IDs; derive coverage from FORMATS rather than a fixed claimed count. Raster-to-SVG is unsupported. HEIC and AVIF encoding through libheif are offered only when the loaded library can instantiate the matching encoder. AVIF decoding requires a libheif build with an AV1 decoder.
The matrix also generates AV1 video in MP4, WebM and MKV and runs every supported target with the same motion, pattern, stream, duration and audio checks. AV1 labels are distinct in logs and JSON reports. A ready FFmpeg without a software AV1 decoder must fail these cases. CONVT_MATRIX_AV1_FFMPEG=/absolute/path/to/trusted/ffmpeg selects a separate libaom-enabled encoder for fixture generation when the shipped FFmpeg has a decoder only, as on Mac. Conversion still uses CONVT_FFMPEG. Missing fixture-generation tooling is an explicit prerequisite failure, not a decoder skip.
Runtime fixtures and Office validators live in scripts/matrix-fixtures.py, and Rust image/media checks live in crates/convt-engines/tests/support/mod.rs. Update those sources when adding formats. Never add fixture binaries. The older shell fixture script above remains useful for manual CLI checks.
On this Linux machine, all six engines and validation tools are present. A passing run without those tools proves less; always report the skips. Linux file-manager tests emulate their commands and do not prove that a real desktop menu is visible.
bun run bundle:linux builds the relocatable payload using hash-locked inputs. bun run bundle:appimage wraps it. Set CONVT_BUNDLE_OUT to a fresh directory for repeat builds and CONVT_BUNDLE_CACHE to reuse downloads; every cached input is verified again. The CLI, GUI, codec libraries and validation tools build in pinned manylinux/AlmaLinux 8 with a glibc 2.28 ceiling checked on every ELF. The harness uses these baseline validation tools, not a host-built runner. Runtime discovery searches explicit overrides, the executable's fixed package layout and system paths. Use an absolute CONVT_LIBHEIF_PLUGIN_DIR for codec tests outside the bundle. Relative plugin paths are ignored; LIBHEIF_PLUGIN_PATH is not a convt plugin override. It never searches arbitrary ancestors.
bash packaging/linux/validate.sh /absolute/path/to/convt runs the semantic matrix through the packaged CLI in Ubuntu 22.04, Debian 12, Debian stable-slim and Ubuntu 24.04 with networking disabled. CONVT_TEST_FEDORA=1 adds Fedora. CONVT_TEST_USE_LOCAL_IMAGES=1 uses cached test images without a registry request and still records their image IDs and digests. CONVT_TEST_DISTROS="ubuntu:24.04 fedora:latest" limits a diagnostic rerun to those images; a release proof still covers the full set. The containers receive only the bundle and an isolated test interpreter and matrix runner, never host library directories or sockets. CONVT_BUNDLE_REPORT selects the report directory. CONVT_BIN switches host matrix conversions to a specific CLI; targets must match the test registry, so point both at the same native bundle using its library/plugin paths. CONVT_MATRIX_HELPER overrides the Python helper's path for containers.
Without a document pack, documents must have no targets and the matrix reports those inputs skipped. python3 packaging/linux/build-document-pack.py <fresh-output-directory> produces a local proof pack from installed LibreOffice with a private native closure and relocated bootstrap. It makes no downloads and is not a pinned public-release pack. Set CONVT_DOCUMENT_PACK to its documents directory when running the container harness. To prove installation and per-user discovery too, use CONVT_DOCUMENT_ARCHIVE pointing to a directory containing documents.tar.gz and documents.sha256; each container installs and verifies that archive explicitly before running the matrix. Validate all document cases as well as non-document cases.
Use convt pack status documents or convt pack status for the same offline status check. Test install/status/removal with temporary CONVT_DATA_DIR, CONVT_CONFIG_DIR and CONVT_LICENSE_STORE=file. convt pack install documents --source file:///absolute/path/documents.tar.gz --sha256 <digest> is an explicit local test source. Discovery still requires that digest to equal CONVT_DOCUMENT_PACK_SHA256 embedded at build time; a source override cannot establish a release trust pin. Build the verification bundle with the proof archive digest, CONVT_DOCUMENT_PACK_VERSION, and the placeholder URL. Default installation fails offline before any request until release CI embeds the real URL and digest. Pack tests cover resume, complete cached archives, checksum rejection, unsafe archive entries, pinned receipts, writable paths, symlinked launchers and removal roots, reinstall verification, inherited lock descriptors, staging-orphan cleanup and publication recovery. Status, discovery and conversions never download a pack. See docs/document-pack.md for the UI contract and remaining release gates.
Remove only the directory you created: rm -rf "$work". Keep it while review is pending if the outputs are your evidence, and give its path.
Rebuild the current sources with bun run bundle:linux into a fresh CONVT_BUNDLE_OUT, then replace the old payload only after the build and ELF audit succeed. Preserve packaging/out/verification. Set SOURCE_DATE_EPOCH to the existing payload's epoch when comparing builds. bun run package:deb, bun run package:rpm and bun run package:linux wrap that exact payload using standard tools inside digest-pinned containers. They do not rebuild Rust binaries. CONVT_PACKAGE_VERSION and CONVT_PACKAGE_RELEASE select package metadata.
The packages put the payload in /opt/convt, symlink /usr/bin/convt and /usr/bin/convt-app, and install desktop metadata, icons, Nautilus Python, Nemo actions and Dolphin service menus under /usr/share. Static menus open Quick convert so targets reflect the installed engines. Thunar has no system custom-action location: run python3 /usr/share/convt/integrations/install.py --thunar as the user who wants those actions. An explicit per-user installer run retires that user's old entries when system integration is present. Package scripts never inspect user homes.
Run bun run test:packages after building both current packages and an older release under packaging/out/verification/packages/older. To prepare an older package, use the saved previous payload with CONVT_BUNDLE_OUT and CONVT_PACKAGE_RELEASE=0, then copy its packages into that directory. The runner installs the older build and upgrades with apt or dnf. Dependency installation can use the network. The three full conversion passes run in fresh containers with --network none, using the installed /usr/bin/convt through an environment-clearing wrapper: 349 non-document cases, 579 cases with distro LibreOffice, then 349 after LibreOffice removal. Distro Office runs use one matrix worker by default to avoid concurrent first-profile startup collisions; CONVT_PACKAGE_MATRIX_JOBS overrides that count. CONVT_PACKAGE_LIFECYCLE_ONLY=1 reruns metadata, upgrade and removal checks without repeating already verified matrices. The validator uses separate baseline-built tools; its library overrides do not reach the CLI. Reports include per-case semantic results, engine lists, metadata validation, GUI ldd, lint and reinstall/removal checks. CONVT_PACKAGE_DISTROS can select names from package-images.lock.json.
Package verification must also compare two package builds byte for byte, inspect their dependency metadata and maintainer scripts, and prove user data survives removal. No GUI launch is needed for ldd. Lintian and rpmlint policy exceptions must name the actual finding and explain the bundled /opt layout rather than suppress unknown warnings. No package is signed; P11 release CI must sign copies after reproducibility checks. Document packs and corresponding-source publication remain separate release gates.
Read docs/release.md before building release artifacts. cargo test -p convt-update checks valid and tampered signatures, wrong keys, schema rejection, expiry, metadata rollback and license coverage. crates/convt-update/examples/check-manifest.rs is a tiny offline consumer for checking a production-ready Bun-signed fixture.
Freeze one source tree with python3 scripts/release/source.py snapshot /tmp/convt-release-source and use CONVT_RELEASE_SOURCE_TREE for both builds when agents share the checkout. With a fixed SOURCE_DATE_EPOCH and the same external CONVT_UPDATE_SIGNING_KEY, run bun run release:linux --verification-only into two fresh output roots. Compare all artifacts and manifests with scripts/release/compare.py. Run scripts/release/rebuild-cli.sh on the source archive; it builds offline in an owned, labeled clean container and performs a real SVG-to-PNG conversion. Also run cargo test and bun run rs:check.
Verification manifests have distribution_ready=false. Production --dry-run and real upload fail while any corresponding-source or notice gate remains. Linux release collection now checks source-built FFmpeg, the exact PDFium revision and DEPS sources, native RPM/GCC recipes and the source-built AppImage runtime. The Linux archive excludes unrelated SDK-derived Mac crate sources and preserves original manifests, pins and an identical compilation graph in its derivation receipt. A clean offline rebuild alone does not establish native source coverage. Use production --dry-run with separate external keys to test distribution_ready=true; adding uncovered Mac or Windows artifacts must make the manifest unavailable. Keep publication gaps explicit in the final PASS/FAIL/NOT CHECKED report. Never run live uploads or hosted workflows as part of a local release dry run.
Conversion, duration probing and desktop thumbnails share a local-only FFmpeg policy. It permits file and pipe protocols and self-contained media demuxers. HLS, DASH and concat playlists are refused, including playlists referencing other local files. Do not remove the demuxer allowlist merely because network protocols are blocked.
On the Linux verification host, run CONVT_REQUIRE_MEDIA_TOOLS=1 cargo test -p convt-engines local_ -- --nocapture. This requires both /usr/bin tools and the tools under packaging/out/convt. The DASH test opens an owned loopback listener and tests a disguised MP4 and a Linux memfd through duration, conversion and the shared thumbnail command. Both toolsets must produce zero HTTP requests. The playlist test verifies HLS, DASH and concat refusal. Run bun run test:matrix afterward and retain the full 579 cases when all engines are available.
© opencoredev, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (scripts) in .agents/skills/test-convt-cli of opencoredev/convt.
Open the folder on GitHubat commit 9214ba0
Test Convt CLI next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Test Convt CLI this skillopencoredev/convt | 187 | — | ~7.7k | Automated safety check: Pass | AGPL-3.0 | |
| Record Demolibnativeapi/nativeapi | 161 | — | ~2.9k | Automated safety check: Pass | MIT | |
| Env Setupwwwzhouhui/skills_collection | 282 | — | ~3.5k | Automated safety check: Notes | None | |
| Ffmpeg Skilljiushiwon/wg-skills | 112 | — | ~1.4k | Automated safety check: Pass | Apache-2.0 | |
| Youtube DownloaderOpenMinis/MinisSkills | 444 | — | ~1.8k | Automated safety check: Pass | MIT | |
| Video EditingLeoYeAI/openclaw-master-skills | 2.2k | — | ~2.7k | Automated safety check: Notes | MIT |
libnativeapi/nativeapi
Record a demo video of a desktop app — launch it, play a scripted scenario with smooth synthetic mouse input, and capture the screen (cursor and click highlights included) straight to an…
wwwzhouhui/skills_collection
Checking and provisioning the machine's environment for the video-agent-kit plugin — probing for ffmpeg/ffprobe that actually carry the encoders and filters we render with (libx264/aac/libmp3lame…
jiushiwon/wg-skills
FFmpeg 多媒体处理技能 — 将自然语言描述转为正确的 ffmpeg 命令,覆盖视频剪辑、转码、水印、合成、提取、生成等操作。内置一键安装脚本(Windows/Mac/Linux)。触发词:ffmpeg、视频剪辑、视频裁剪、视频转码、视频压缩、去水印、加水印、视频拼接、视频合成、提取音频、视频转…
OpenMinis/MinisSkills
Download YouTube videos or extract audio using yt-dlp + ffmpeg in the Linux shell.
LeoYeAI/openclaw-master-skills
Automated video editing skill for talk/vlog/standup videos. An agent skill from LeoYeAI/openclaw-master-skills.
RightNow-AI/openfang
Command reference for cutting clips from online video: yt-dlp downloads, whisper transcription, SRT subtitle files and ffmpeg processing, with Windows, macOS and Linux differences.
opencoredev/convt
Run the headless window tests for the convt GPUI desktop app (crates/convt-app), and build, launch and screenshot it under Xvfb or natively on macOS and Windows.
opencoredev/convt
Run and verify the convt.app website (apps/web, TanStack Start on Cloudflare Workers) and its billing Worker (apps/billing) locally, with Postgres, Mailpit, the OAuth mock and the Polar and Resend…
opencoredev/convt
Run and verify the convt jobs API, Postgres queue, object storage, sandbox worker and metering locally.
Works with
Categories
Test convt conversions end to end through the convt CLI, the engines in convt-engines, routing in convt-core, and the Linux file-manager menus in integrations/linux. Test Convt CLI is an agent skill from opencoredev/convt. Test convt conversions end to end through the convt CLI, the engines in convt-engines, routing in convt-core, and the Linux file-manager menus in integrations/linux.
Test Convt CLI fits situations like: changing an engine; asked to reproduce a conversion bug; prove a conversion works.
Run `npx skills add opencoredev/convt --skill test-convt-cli -a claude-code`. Or copy the skill folder (.agents/skills/test-convt-cli in opencoredev/convt) into .claude/skills/test-convt-cli in your project. Claude Code loads it when a task matches its description.
Run `npx skills add opencoredev/convt --skill test-convt-cli -a codex`. Or copy the skill folder (.agents/skills/test-convt-cli in opencoredev/convt) into .agents/skills/test-convt-cli in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add opencoredev/convt --skill test-convt-cli -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/test-convt-cli, .gemini/skills/test-convt-cli, .github/skills/test-convt-cli and .opencode/skills/test-convt-cli in your project.
Going by SKILL.md and its folder, Test Convt CLI needs a shell for the scripts in its folder, the command-line tools its instructions call (bun, cargo, python3, bash, apt-get and sh) and credentials named CONVT_UPDATE_SIGNING_KEY. Our summary lists: Python 3; A Bash shell.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Test Convt CLI is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.7k tokens (SKILL.md is roughly 31k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Test Convt CLI: Record Demo (libnativeapi/nativeapi, 161 stars), Env Setup (wwwzhouhui/skills_collection, 282 stars), Ffmpeg Skill (jiushiwon/wg-skills, 112 stars) and Youtube Downloader (OpenMinis/MinisSkills, 444 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
opencoredev (a GitHub organization) maintains it in opencoredev/convt, which has 187 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on October 8, 2026.
Source: opencoredev/convt on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.