A compact media workshop for your terminal and agent automation. Website: fram.serhiifotex.dev
Fram crops, resizes, compresses, and converts images; cuts, resizes, crops, compresses, changes FPS, strips audio, extracts frames, and makes GIFs from videos. The CLI uses a typed processing core.
Early hobby project. The strict CLI and basic interactive TUI are the main focus.
- Scriptable CLI commands for image and video edits.
- Interactive terminal UI for quick manual workflows.
- Bundled agent skill so AI coding agents can drive Fram directly.
- Shared core used by the CLI.
- FFmpeg-backed video processing with Pillow-backed image operations.
- Small codebase intended to stay hackable.
Fram requires Python 3.11+ and FFmpeg. For manual global installs, use either uv or pipx.
ffmpeg -version
uv --version
pipx --versionInstall with the script:
curl -LsSf https://fram.serhiifotex.dev/install.sh | shWindows PowerShell:
powershell -ExecutionPolicy Bypass -c "irm https://fram.serhiifotex.dev/install.ps1 | iex"Homebrew (installs FFmpeg automatically):
brew install sergio-prog/tap/framManual install with uv tool:
uv tool install git+https://github.com/Sergio-prog/fram.gitManual install with pipx:
pipx install git+https://github.com/Sergio-prog/fram.gitAfter the first PyPI release, the manual commands become:
uv tool install fram
pipx install framFrom a local checkout:
scripts/install.sh
uv tool install .
pipx install .For development:
uv --version
uv sync --all-extras
uv run fram --helpFram ships an agent skill at skills/SKILL.md so AI coding agents (Claude Code, and any tool that reads the Agent Skills format) can discover and drive the CLI.
Install it for Claude Code by copying the skill into your skills directory:
npx skills add Sergio-prog/framUse .claude/skills/fram/ inside a project instead of ~/.claude/skills/ to scope it to a single repository. Once installed, the agent picks up Fram automatically when a task involves inspecting or editing local image and video files.
fram info image.jpg
fram resize image.jpg 128x128 -o image-small.jpg
fram convert image.png webp -o image.webp
fram cut video.mp4 --start 00:00:05 --end 00:00:12 -o clip.mp4
fram gif video.mp4 --fps 12 --width 480 -o clip.gif
fram strip-audio video.mp4 -o silent.mp4Help works both ways:
fram resize --help
fram help resizeUpdates:
fram update --check
fram updateFram checks GitHub Releases occasionally and prints a small notice in interactive terminals when a newer release exists. Set FRAM_UPDATE_CHECK=0 to hide update checks.
fram resize image.jpg 128x128 -o image-small.jpg
fram crop image.jpg 128x128 --anchor center -o avatar.jpg
fram compress-image image.jpg --quality 80 -o compressed.webp
fram convert image.png webp -o image.webp
fram rotate image.jpg 90 -o rotated.jpg
fram flip image.jpg --horizontal -o flipped.jpg
fram strip-metadata image.jpg -o clean.jpg
fram blur image.jpg --radius 2 -o blurred.jpg
fram grayscale image.jpg -o gray.jpg
fram adjust image.jpg --brightness 1.1 --contrast 1.2 -o adjusted.jpg
fram sharpen image.jpg --factor 2 -o sharp.jpg
fram watermark image.jpg "FRAM" --position bottom-right -o watermarked.png
fram upscale image.jpg --factor 2 -o large.jpg
fram auto-orient image.jpg -o oriented.jpg
fram background transparent.png white -o flattened.jpgfram cut video.mp4 --start 00:00:05 --end 00:00:12 -o clip.mp4
fram cut video.mp4 --start 5 --duration 10 -o clip.mp4
fram fps video.mp4 24 -o video-24fps.mp4
fram compress-video video.mp4 --crf 24 --preset medium -o smaller.mp4
fram strip-audio video.mp4 -o silent.mp4
fram extract-audio video.mp4 -o audio.m4a
fram extract-frame video.mp4 --at 00:00:05 -o frame.png
fram gif video.mp4 --fps 12 --width 480 -o clip.gif
fram speed video.mp4 2 -o fast.mp4
fram reverse video.mp4 --no-audio -o reversed.mp4
fram grayscale video.mp4 -o gray.mp4
fram rotate video.mp4 90 -o rotated.mp4
fram flip video.mp4 --horizontal -o flipped.mp4
fram mute-audio video.mp4 -o muted.mp4
fram thumbnail video.mp4 --at 00:00:05 -o thumbnail.png
fram contact-sheet video.mp4 --columns 3 --rows 3 -o sheet.png
fram extract-subtitles video.mp4 -o subtitles.srtfram
fram image.jpg
fram video.mp4Interactive preview uses terminal image protocols through textual-image; videos show an extracted frame.
TUI shortcuts:
i: toggle detailed infoa: focus actionsd: drop last operationUp/Down: switch active sliderLeft/Right: adjust active sliderr: runq: quit
Images:
- input:
jpg,jpeg,png,webp,bmp,tif,tiff - output:
jpg,png,webp - SVG is detected, but true SVG editing is deferred.
Videos:
- input: common FFmpeg-readable formats like
mp4,mov,mkv,webm,avi,gif - output: depends on output suffix and local FFmpeg codecs
uv sync --all-extras
uv run --all-extras --group dev python -m pytest
uv run --all-extras --group dev ruff check .Docs:
MIT. See LICENSE.
