Cirax
Universal local conversion hub for Linux. Every format to every format, fully offline, by routing between best-in-class open-source engines (FFmpeg, libvips, ImageMagick, LibreOffice, Pandoc, Calibre, 7-Zip, qpdf...) plus modern local AI models (GLM-OCR vision OCR via Ollama).
Cirax doesn't reimplement codecs — it composes engines. A declarative YAML registry describes what each installed engine can read and write; a router finds the best chain (direct, or through pivot formats like PDF/PNG/WAV/JSON) and executes it. See PLAN.md for the full architecture and roadmap.
Install
PyPI (once published — make publish-pypi):
uv tool install cirax # or: pipx install cirax
curl one-liner (bootstraps uv, installs as a uv tool):
CIRAX_SRC=. sh install.sh # from this checkout
CIRAX_REPO=https://github.com/baselanaya/Cirax sh <(curl -fsSL \
https://raw.githubusercontent.com/baselanaya/Cirax/main/install.sh)
Arch/AUR — PKGBUILD in packaging/ (community AUR upload pending).
npm wrapper — ships the Python source, bootstraps a private venv on first run (npm ≥ 12 gates lifecycle scripts, so the bin shim self-installs):
cd npm && npm run build:python && npm pack # when publishing
npm install -g ./cirax-0.3.0.tgz && cirax doctor
Development (uv-managed):
uv sync # create .venv, install deps + cirax (editable)
uv run cirax doctor # or: . .venv/bin/activate
make test # 31-check smoke suite
Usage
cirax detect photo.heic # what is this file?
cirax plan report.docx # list every reachable target + route
cirax plan report.docx png # show the exact chain for one target
cirax presets # list engine presets
cirax convert report.docx png # docx -> pdf (libreoffice) -> png (pdftoppm)
cirax convert song.flac -t opus # via ffmpeg
cirax convert video.mov out.mkv --preset web720 # quality presets
cirax convert doc.pdf page.png --pages all # all pages -> page-01.png, ...
cirax convert a.png b.png c.png -t webp # batch
cirax convert photos.zip out.7z # extract -> recreate (staged)
# AI OCR — GLM-OCR vision model, fully offline after `ollama pull glm-ocr`
cirax convert scan.png text.txt # via GLM-OCR (tesseract fallback)
cirax convert scan.png notes --to md # markdown layout preservation
cirax convert photo.jpg clean.jpg # strip EXIF/GPS (exiftool ops route)
cirax convert win.txt unix.txt # CRLF -> LF (dos2unix ops route)
cirax convert l1.txt u8.txt --engine iconv --preset latin1-utf8 # charset ops
# 3D, VM disks, geospatial (engines optional; doctor shows availability)
cirax convert model.obj model.glb # assimp
cirax convert disk.qcow2 disk.vdi # qemu-img
cirax convert area.geojson area.gpkg # GDAL
# watch a folder: new files are converted as they appear
cirax watch ~/scans -t pdf --out ~/documents
# local web UI — upload in the browser, convert, download
cirax serve # http://127.0.0.1:8400
# sandboxing — default is auto: every job runs in bubblewrap with no
# network, read-only filesystem, and writes confined to the job workspace
# and output directory. `--sandbox on` to require it, `off` to disable.
Status — Phase 4 (packaging & publishing)
Working: engine probing, doctor capability matrix, multi-engine chain
routing, presets, multi-page PDF raster, batch, ffmpeg progress, staged
archive repacking, office chains (md→docx→pdf via pandoc+LibreOffice),
ebooks (pandoc + Calibre), metadata stripping, line-ending/charset ops,
GLM-OCR (zai-org's ~1.3B vision model via Ollama — MIT, one
ollama pull, then fully offline; tesseract/ocrmypdf fallback), and:
-
Sandboxed jobs — when
bwrapis present (it is, on Arch), every conversion runs in a bubblewrap jail: no network, no IPC, read-only filesystem, writes confined to the job workspace and the output folder. AI engines that talk to the local Ollama daemon opt out explicitly. -
cirax watch— point it at a folder and every new file is converted to the target format automatically (state in.cirax-watch.json). -
3D / VM disks / geospatial — assimp (obj↔glb↔stl↔ply...), qemu-img (qcow2↔vdi↔vmdk↔vhd), GDAL (geojson↔gpkg↔kml).
-
31-check smoke suite, sandboxed by default.
-
cirax serve— local web UI (Python stdlib only): drag-and-drop upload, target-format picker, live engine matrix, download the result. Loopback by default; uploads run through the same sandboxed pipeline. -
Packaging:
packaging/PKGBUILD+.SRCINFOfor Arch/AUR; PyPI-ready sdist+wheel (make publish-pypi); npm tarball (make publish-npm). -
Flatpak intentionally skipped: Cirax treats engines as system dependencies (40+ of them); bundling them per-sandbox would duplicate the distro. Native packaging is the right fit.
Remaining: AUR upload (needs an AUR account), uv publish to PyPI and
npm publish (need account tokens), Blender/Piper adapters.
Layout
src/cirax/
cli.py doctor / formats / detect / plan / presets / convert / watch
registry.py YAML registry loader (formats + engines + presets)
probe.py engine detection, versions, ffmpeg hw-accel
sandbox.py bubblewrap per-job jail (no network, read-only fs)
detect.py input type detection (ext table + file(1))
router.py Dijkstra over the format graph, ranked routes
executor.py template rendering, presets, staged execution, progress
data/
formats.yaml format vocabulary + pivots + ext table
engines/*.yaml one file per domain, one stanza per engine
install.sh curl installer (uv tool bootstrap)
npm/ npm wrapper package (bin shim + self-installing core)
tests/smoke.sh end-to-end suite
Adding an engine
Drop a YAML stanza in src/cirax/data/engines/ — inputs, outputs, a command
template, optional per-format flags and presets — and the router picks it up.
- engine: mycodec
binary: mycodec
package: mycodec
presets:
web: {flags: {image/myfmt: "-q 70"}}
routes:
- from: [image/png]
to: [image/myfmt]
lossless: true
priority: 90
command: "mycodec encode {input} {flags} {output}"
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cirax-0.3.1.tar.gz.
File metadata
- Download URL: cirax-0.3.1.tar.gz
- Upload date:
- Size: 59.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28436dddbccd7f20b21a5b19686c50ae8c722dbbd7d78cef00904ed7e919dfee
|
|
| MD5 |
fce3a36c8b6afaf7b0144e0580170a11
|
|
| BLAKE2b-256 |
20e8beaf4cac0a1085efa263de903a746ca2b830a7e1a4e6df5dd79efd956472
|
Provenance
The following attestation bundles were made for cirax-0.3.1.tar.gz:
Publisher:
publish.yml on baselanaya/Cirax
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cirax-0.3.1.tar.gz -
Subject digest:
28436dddbccd7f20b21a5b19686c50ae8c722dbbd7d78cef00904ed7e919dfee - Sigstore transparency entry: 2688196568
- Sigstore integration time:
-
Permalink:
baselanaya/Cirax@8b9c6d7f5d011e4a160d0a1684db93466e7a6fd7 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/baselanaya
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8b9c6d7f5d011e4a160d0a1684db93466e7a6fd7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cirax-0.3.1-py3-none-any.whl.
File metadata
- Download URL: cirax-0.3.1-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bafef8c10c551c9ba9f4f40338400e0a6b777bc02dfba2f19d62f4108f27d9fc
|
|
| MD5 |
d2d03b6041d6663369cbc79320e96030
|
|
| BLAKE2b-256 |
b36019a0eebf1b4736451dc621edebd3c5990eb3231ae1cd255a94b797a446b3
|
Provenance
The following attestation bundles were made for cirax-0.3.1-py3-none-any.whl:
Publisher:
publish.yml on baselanaya/Cirax
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cirax-0.3.1-py3-none-any.whl -
Subject digest:
bafef8c10c551c9ba9f4f40338400e0a6b777bc02dfba2f19d62f4108f27d9fc - Sigstore transparency entry: 2688196659
- Sigstore integration time:
-
Permalink:
baselanaya/Cirax@8b9c6d7f5d011e4a160d0a1684db93466e7a6fd7 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/baselanaya
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8b9c6d7f5d011e4a160d0a1684db93466e7a6fd7 -
Trigger Event:
push
-
Statement type: