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.
- cirax-0.3.1/.github/workflows/ci.yml +52 -0
- cirax-0.3.1/.github/workflows/publish.yml +59 -0
- cirax-0.3.1/.gitignore +11 -0
- cirax-0.3.1/.python-version +1 -0
- cirax-0.3.1/LICENSE +21 -0
- cirax-0.3.1/Makefile +28 -0
- cirax-0.3.1/PKG-INFO +165 -0
- cirax-0.3.1/PLAN.md +335 -0
- cirax-0.3.1/README.md +153 -0
- cirax-0.3.1/install.sh +67 -0
- cirax-0.3.1/npm/bin/cirax.js +45 -0
- cirax-0.3.1/npm/package-lock.json +24 -0
- cirax-0.3.1/npm/package.json +38 -0
- cirax-0.3.1/npm/scripts/bundle-python.sh +12 -0
- cirax-0.3.1/npm/scripts/postinstall.js +81 -0
- cirax-0.3.1/packaging/.SRCINFO +59 -0
- cirax-0.3.1/packaging/PKGBUILD +69 -0
- cirax-0.3.1/pyproject.toml +22 -0
- cirax-0.3.1/src/cirax/__init__.py +3 -0
- cirax-0.3.1/src/cirax/__main__.py +4 -0
- cirax-0.3.1/src/cirax/cli.py +417 -0
- cirax-0.3.1/src/cirax/data/engines/ai.yaml +66 -0
- cirax-0.3.1/src/cirax/data/engines/archives.yaml +92 -0
- cirax-0.3.1/src/cirax/data/engines/av.yaml +194 -0
- cirax-0.3.1/src/cirax/data/engines/data.yaml +141 -0
- cirax-0.3.1/src/cirax/data/engines/docs.yaml +122 -0
- cirax-0.3.1/src/cirax/data/engines/images.yaml +265 -0
- cirax-0.3.1/src/cirax/data/engines/misc.yaml +106 -0
- cirax-0.3.1/src/cirax/data/engines/pdf.yaml +162 -0
- cirax-0.3.1/src/cirax/data/formats.yaml +280 -0
- cirax-0.3.1/src/cirax/detect.py +38 -0
- cirax-0.3.1/src/cirax/executor.py +355 -0
- cirax-0.3.1/src/cirax/probe.py +63 -0
- cirax-0.3.1/src/cirax/registry.py +180 -0
- cirax-0.3.1/src/cirax/router.py +137 -0
- cirax-0.3.1/src/cirax/sandbox.py +82 -0
- cirax-0.3.1/src/cirax/webui.py +258 -0
- cirax-0.3.1/tests/smoke.sh +162 -0
- 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 @@
|
|
|
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
|
+
```
|