cirax 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. cirax-0.3.1/.github/workflows/ci.yml +52 -0
  2. cirax-0.3.1/.github/workflows/publish.yml +59 -0
  3. cirax-0.3.1/.gitignore +11 -0
  4. cirax-0.3.1/.python-version +1 -0
  5. cirax-0.3.1/LICENSE +21 -0
  6. cirax-0.3.1/Makefile +28 -0
  7. cirax-0.3.1/PKG-INFO +165 -0
  8. cirax-0.3.1/PLAN.md +335 -0
  9. cirax-0.3.1/README.md +153 -0
  10. cirax-0.3.1/install.sh +67 -0
  11. cirax-0.3.1/npm/bin/cirax.js +45 -0
  12. cirax-0.3.1/npm/package-lock.json +24 -0
  13. cirax-0.3.1/npm/package.json +38 -0
  14. cirax-0.3.1/npm/scripts/bundle-python.sh +12 -0
  15. cirax-0.3.1/npm/scripts/postinstall.js +81 -0
  16. cirax-0.3.1/packaging/.SRCINFO +59 -0
  17. cirax-0.3.1/packaging/PKGBUILD +69 -0
  18. cirax-0.3.1/pyproject.toml +22 -0
  19. cirax-0.3.1/src/cirax/__init__.py +3 -0
  20. cirax-0.3.1/src/cirax/__main__.py +4 -0
  21. cirax-0.3.1/src/cirax/cli.py +417 -0
  22. cirax-0.3.1/src/cirax/data/engines/ai.yaml +66 -0
  23. cirax-0.3.1/src/cirax/data/engines/archives.yaml +92 -0
  24. cirax-0.3.1/src/cirax/data/engines/av.yaml +194 -0
  25. cirax-0.3.1/src/cirax/data/engines/data.yaml +141 -0
  26. cirax-0.3.1/src/cirax/data/engines/docs.yaml +122 -0
  27. cirax-0.3.1/src/cirax/data/engines/images.yaml +265 -0
  28. cirax-0.3.1/src/cirax/data/engines/misc.yaml +106 -0
  29. cirax-0.3.1/src/cirax/data/engines/pdf.yaml +162 -0
  30. cirax-0.3.1/src/cirax/data/formats.yaml +280 -0
  31. cirax-0.3.1/src/cirax/detect.py +38 -0
  32. cirax-0.3.1/src/cirax/executor.py +355 -0
  33. cirax-0.3.1/src/cirax/probe.py +63 -0
  34. cirax-0.3.1/src/cirax/registry.py +180 -0
  35. cirax-0.3.1/src/cirax/router.py +137 -0
  36. cirax-0.3.1/src/cirax/sandbox.py +82 -0
  37. cirax-0.3.1/src/cirax/webui.py +258 -0
  38. cirax-0.3.1/tests/smoke.sh +162 -0
  39. cirax-0.3.1/uv.lock +125 -0
@@ -0,0 +1,52 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: astral-sh/setup-uv@v5
14
+ - name: install a subset of engines
15
+ run: |
16
+ sudo apt-get update
17
+ sudo apt-get install -y --no-install-recommends \
18
+ libvips-tools p7zip-full zstd ghostscript poppler-utils file
19
+ - name: install cirax
20
+ run: uv sync
21
+ - name: doctor
22
+ run: uv run cirax doctor
23
+ - name: conversion checks
24
+ run: |
25
+ set -e
26
+ T=$(mktemp -d); cd "$T"
27
+ CIRAX="$GITHUB_WORKSPACE/.venv/bin/cirax"
28
+ printf 'hello cirax\n' > doc.txt
29
+ echo "[1] txt -> zst"
30
+ $CIRAX convert -q doc.txt -t zst
31
+ file -b doc.zst | grep -qiE "zstandard|zstd"
32
+ echo "[2] zip -> 7z"
33
+ 7z a -bso0 archive.zip doc.txt
34
+ $CIRAX convert -q archive.zip -t 7z
35
+ file -b archive.7z | grep -qi "7-zip"
36
+ echo "[3] png -> webp"
37
+ python3 - <<'PY'
38
+ import base64, pathlib
39
+ # 1x1 transparent PNG
40
+ png = base64.b64decode(
41
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4"
42
+ "nGNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==")
43
+ pathlib.Path("dot.png").write_bytes(png)
44
+ PY
45
+ $CIRAX convert -q dot.png -t webp
46
+ file -b dot.webp | grep -qiE "web.?p"
47
+ echo "[4] ps -> pdf -> txt"
48
+ printf '%%!PS\n/Helvetica findfont 20 scalefont setfont 72 700 moveto (Hello Cirax) show showpage\n' > doc.ps
49
+ $CIRAX convert -q doc.ps readme.pdf
50
+ $CIRAX convert -q readme.pdf -t txt
51
+ grep -qi cirax readme.txt
52
+ echo "ci conversions ok"
@@ -0,0 +1,59 @@
1
+ name: publish
2
+
3
+ # Publish on version tags (v0.3.0, ...) or manually via workflow_dispatch.
4
+ #
5
+ # PyPI: uses OIDC trusted publishing — no token needed. The pending
6
+ # publisher on pypi.org must match exactly:
7
+ # project: cirax · owner: baselanaya · repository: Cirax ·
8
+ # workflow: publish.yml · environment: (blank)
9
+ #
10
+ # Alternative: add a PYPI_API_TOKEN secret and a `password:` input to the
11
+ # gh-action-pypi-publish step.
12
+ #
13
+ # npm: opt-in via workflow_dispatch (checkbox) — requires the NPM_TOKEN
14
+ # secret (npmjs.com → Access Tokens → Granular, Read & publish). To make
15
+ # npm automatic on tags, add NPM_TOKEN and change the job condition to
16
+ # `startsWith(github.ref, 'refs/tags/v')`.
17
+
18
+ on:
19
+ push:
20
+ tags: ["v*"]
21
+ workflow_dispatch:
22
+ inputs:
23
+ npm:
24
+ description: "also publish the npm wrapper (requires NPM_TOKEN secret)"
25
+ type: boolean
26
+ default: false
27
+
28
+ jobs:
29
+ pypi:
30
+ if: startsWith(github.ref, 'refs/tags/v')
31
+ runs-on: ubuntu-latest
32
+ permissions:
33
+ id-token: write # trusted publishing (OIDC)
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - uses: astral-sh/setup-uv@v5
37
+ - name: build sdist + wheel
38
+ run: uv build
39
+ - name: publish to PyPI
40
+ uses: pypa/gh-action-pypi-publish@release/v1
41
+
42
+ npm:
43
+ if: github.event_name == 'workflow_dispatch' && inputs.npm == true
44
+ runs-on: ubuntu-latest
45
+ defaults:
46
+ run:
47
+ working-directory: npm
48
+ steps:
49
+ - uses: actions/checkout@v4
50
+ - uses: actions/setup-node@v4
51
+ with:
52
+ node-version: 20
53
+ registry-url: https://registry.npmjs.org
54
+ - name: bundle python core
55
+ run: npm run build:python
56
+ - name: publish to npm
57
+ run: npm publish
58
+ env:
59
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
cirax-0.3.1/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ npm/node_modules/
8
+ npm/.venv/
9
+ npm/python/
10
+ npm/*.tgz
11
+ .claude/
@@ -0,0 +1 @@
1
+ 3.12
cirax-0.3.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cirax contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
cirax-0.3.1/Makefile ADDED
@@ -0,0 +1,28 @@
1
+ .PHONY: install test doctor serve npm srcinfo publish-pypi publish-npm clean
2
+
3
+ install: ## create the venv and install cirax (uv)
4
+ uv sync
5
+
6
+ test: ## run the smoke suite
7
+ uv run bash tests/smoke.sh
8
+
9
+ doctor: ## report engine capability matrix
10
+ uv run cirax doctor --show-missing
11
+
12
+ serve: ## local web UI on http://127.0.0.1:8400
13
+ uv run cirax serve
14
+
15
+ npm: ## test the npm wrapper from a git checkout
16
+ cd npm && npm install --no-fund --no-audit && ./node_modules/.bin/cirax --version
17
+
18
+ srcinfo: ## regenerate AUR .SRCINFO
19
+ cd packaging && makepkg --printsrcinfo > .SRCINFO
20
+
21
+ publish-pypi: ## build and publish to PyPI (needs UV_PUBLISH_TOKEN)
22
+ uv build && uv publish
23
+
24
+ publish-npm: ## bundle python source and publish the npm wrapper (needs npm login)
25
+ cd npm && npm run build:python && npm publish
26
+
27
+ clean:
28
+ rm -rf .venv dist build npm/python npm/.venv npm/node_modules
cirax-0.3.1/PKG-INFO ADDED
@@ -0,0 +1,165 @@
1
+ Metadata-Version: 2.5
2
+ Name: cirax
3
+ Version: 0.3.1
4
+ Summary: Universal local conversion hub — every format to every format, fully offline on Linux
5
+ Author: Cirax
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: pyyaml>=6.0
10
+ Requires-Dist: rich>=13.0
11
+ Description-Content-Type: text/markdown
12
+
13
+ # Cirax
14
+
15
+ **Universal local conversion hub for Linux.** Every format to every format,
16
+ fully offline, by routing between best-in-class open-source engines
17
+ (FFmpeg, libvips, ImageMagick, LibreOffice, Pandoc, Calibre, 7-Zip, qpdf...)
18
+ plus modern local AI models (GLM-OCR vision OCR via Ollama).
19
+
20
+ Cirax doesn't reimplement codecs — it *composes* engines. A declarative YAML
21
+ registry describes what each installed engine can read and write; a router
22
+ finds the best chain (direct, or through pivot formats like PDF/PNG/WAV/JSON)
23
+ and executes it. See [PLAN.md](PLAN.md) for the full architecture and roadmap.
24
+
25
+ ## Install
26
+
27
+ **PyPI** (once published — `make publish-pypi`):
28
+
29
+ ```sh
30
+ uv tool install cirax # or: pipx install cirax
31
+ ```
32
+
33
+ **curl one-liner** (bootstraps `uv`, installs as a `uv tool`):
34
+
35
+ ```sh
36
+ CIRAX_SRC=. sh install.sh # from this checkout
37
+ CIRAX_REPO=https://github.com/baselanaya/Cirax sh <(curl -fsSL \
38
+ https://raw.githubusercontent.com/baselanaya/Cirax/main/install.sh)
39
+ ```
40
+
41
+ **Arch/AUR** — PKGBUILD in [`packaging/`](packaging/) (community AUR upload pending).
42
+
43
+ **npm wrapper** — ships the Python source, bootstraps a private venv on first
44
+ run (npm ≥ 12 gates lifecycle scripts, so the bin shim self-installs):
45
+
46
+ ```sh
47
+ cd npm && npm run build:python && npm pack # when publishing
48
+ npm install -g ./cirax-0.3.0.tgz && cirax doctor
49
+ ```
50
+
51
+ **Development** (uv-managed):
52
+
53
+ ```sh
54
+ uv sync # create .venv, install deps + cirax (editable)
55
+ uv run cirax doctor # or: . .venv/bin/activate
56
+ make test # 31-check smoke suite
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ ```sh
62
+ cirax detect photo.heic # what is this file?
63
+ cirax plan report.docx # list every reachable target + route
64
+ cirax plan report.docx png # show the exact chain for one target
65
+ cirax presets # list engine presets
66
+
67
+ cirax convert report.docx png # docx -> pdf (libreoffice) -> png (pdftoppm)
68
+ cirax convert song.flac -t opus # via ffmpeg
69
+ cirax convert video.mov out.mkv --preset web720 # quality presets
70
+ cirax convert doc.pdf page.png --pages all # all pages -> page-01.png, ...
71
+ cirax convert a.png b.png c.png -t webp # batch
72
+ cirax convert photos.zip out.7z # extract -> recreate (staged)
73
+
74
+ # AI OCR — GLM-OCR vision model, fully offline after `ollama pull glm-ocr`
75
+ cirax convert scan.png text.txt # via GLM-OCR (tesseract fallback)
76
+ cirax convert scan.png notes --to md # markdown layout preservation
77
+ cirax convert photo.jpg clean.jpg # strip EXIF/GPS (exiftool ops route)
78
+ cirax convert win.txt unix.txt # CRLF -> LF (dos2unix ops route)
79
+ cirax convert l1.txt u8.txt --engine iconv --preset latin1-utf8 # charset ops
80
+
81
+ # 3D, VM disks, geospatial (engines optional; doctor shows availability)
82
+ cirax convert model.obj model.glb # assimp
83
+ cirax convert disk.qcow2 disk.vdi # qemu-img
84
+ cirax convert area.geojson area.gpkg # GDAL
85
+
86
+ # watch a folder: new files are converted as they appear
87
+ cirax watch ~/scans -t pdf --out ~/documents
88
+
89
+ # local web UI — upload in the browser, convert, download
90
+ cirax serve # http://127.0.0.1:8400
91
+
92
+ # sandboxing — default is auto: every job runs in bubblewrap with no
93
+ # network, read-only filesystem, and writes confined to the job workspace
94
+ # and output directory. `--sandbox on` to require it, `off` to disable.
95
+ ```
96
+
97
+ ## Status — Phase 4 (packaging & publishing)
98
+
99
+ Working: engine probing, `doctor` capability matrix, multi-engine chain
100
+ routing, presets, multi-page PDF raster, batch, ffmpeg progress, staged
101
+ archive repacking, office chains (md→docx→pdf via pandoc+LibreOffice),
102
+ ebooks (pandoc + Calibre), metadata stripping, line-ending/charset ops,
103
+ **GLM-OCR** (zai-org's ~1.3B vision model via Ollama — MIT, one
104
+ `ollama pull`, then fully offline; tesseract/ocrmypdf fallback), and:
105
+
106
+ - **Sandboxed jobs** — when `bwrap` is present (it is, on Arch), every
107
+ conversion runs in a bubblewrap jail: no network, no IPC, read-only
108
+ filesystem, writes confined to the job workspace and the output folder.
109
+ AI engines that talk to the local Ollama daemon opt out explicitly.
110
+ - **`cirax watch`** — point it at a folder and every new file is converted
111
+ to the target format automatically (state in `.cirax-watch.json`).
112
+ - **3D / VM disks / geospatial** — assimp (obj↔glb↔stl↔ply...),
113
+ qemu-img (qcow2↔vdi↔vmdk↔vhd), GDAL (geojson↔gpkg↔kml).
114
+ - 31-check smoke suite, sandboxed by default.
115
+
116
+ - **`cirax serve`** — local web UI (Python stdlib only): drag-and-drop
117
+ upload, target-format picker, live engine matrix, download the result.
118
+ Loopback by default; uploads run through the same sandboxed pipeline.
119
+ - **Packaging**: [`packaging/PKGBUILD`](packaging/) + `.SRCINFO` for
120
+ Arch/AUR; PyPI-ready sdist+wheel (`make publish-pypi`); npm tarball
121
+ (`make publish-npm`).
122
+ - Flatpak intentionally skipped: Cirax treats engines as *system*
123
+ dependencies (40+ of them); bundling them per-sandbox would duplicate
124
+ the distro. Native packaging is the right fit.
125
+
126
+ Remaining: AUR upload (needs an AUR account), `uv publish` to PyPI and
127
+ `npm publish` (need account tokens), Blender/Piper adapters.
128
+
129
+ ## Layout
130
+
131
+ ```
132
+ src/cirax/
133
+ cli.py doctor / formats / detect / plan / presets / convert / watch
134
+ registry.py YAML registry loader (formats + engines + presets)
135
+ probe.py engine detection, versions, ffmpeg hw-accel
136
+ sandbox.py bubblewrap per-job jail (no network, read-only fs)
137
+ detect.py input type detection (ext table + file(1))
138
+ router.py Dijkstra over the format graph, ranked routes
139
+ executor.py template rendering, presets, staged execution, progress
140
+ data/
141
+ formats.yaml format vocabulary + pivots + ext table
142
+ engines/*.yaml one file per domain, one stanza per engine
143
+ install.sh curl installer (uv tool bootstrap)
144
+ npm/ npm wrapper package (bin shim + self-installing core)
145
+ tests/smoke.sh end-to-end suite
146
+ ```
147
+
148
+ ## Adding an engine
149
+
150
+ Drop a YAML stanza in `src/cirax/data/engines/` — inputs, outputs, a command
151
+ template, optional per-format flags and presets — and the router picks it up.
152
+
153
+ ```yaml
154
+ - engine: mycodec
155
+ binary: mycodec
156
+ package: mycodec
157
+ presets:
158
+ web: {flags: {image/myfmt: "-q 70"}}
159
+ routes:
160
+ - from: [image/png]
161
+ to: [image/myfmt]
162
+ lossless: true
163
+ priority: 90
164
+ command: "mycodec encode {input} {flags} {output}"
165
+ ```