aioli-cli 0.1.45__tar.gz → 0.1.48__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.
- aioli_cli-0.1.48/.gitignore +20 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/PKG-INFO +22 -17
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/README.md +21 -16
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/pyproject.toml +24 -10
- aioli_cli-0.1.48/src/aioli_cli/backend_manager.py +1764 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_cli/main.py +217 -4
- aioli_cli-0.1.48/src/aioli_cli/managed.py +252 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_cli/readiness.py +110 -5
- aioli_cli-0.1.48/src/aioli_cli/registry.py +91 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_cli/setup.py +333 -78
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/__init__.py +14 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/advise.py +119 -1
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/config.py +84 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/fetch.py +578 -47
- aioli_cli-0.1.48/src/aioli_contract/model_ids.py +161 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/probe.py +52 -13
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/readiness.py +25 -1
- aioli_cli-0.1.48/src/aioli_contract/short_verb.py +47 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/cli.py +134 -1
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/config.py +52 -17
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/data/models.toml +37 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/launcher.py +358 -30
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/models.py +34 -1
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/models_data.py +139 -8
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_master/cli.py +15 -2
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_master/ops.py +32 -8
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/minimax_comfy.py +40 -1
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/process.py +114 -25
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/yue2.py +13 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/cli_commands/generate_cmd.py +117 -11
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/core/generate.py +56 -2
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/models_data.py +15 -2
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/plugin.py +9 -1
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/presets.py +11 -2
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/server.py +106 -32
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/transport/client.py +180 -10
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_podcast/cast.py +59 -3
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_podcast/cli.py +22 -3
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_podcast/episode.py +125 -9
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/cli.py +100 -10
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/models_data.py +8 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/wgp.py +65 -2
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/cli/generate.py +71 -6
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/core/generation.py +41 -5
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/kokoro.py +7 -2
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/voxcpm.py +3 -2
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/models_data.py +22 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/plugin.py +9 -1
- aioli_cli-0.1.45/.gitignore +0 -11
- aioli_cli-0.1.45/src/aioli_cli/registry.py +0 -50
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/LICENSE +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_cli/_plugins.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_cli/fetch_ui.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_cli/status.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_contract/ui.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/companions.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/gpu.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/plugin.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/presets.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/progress.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/stub.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_image/ui.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_master/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_master/plugin.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/acestep.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/base.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/llm_caption.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/backends/stub.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/cli_commands/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/cli_commands/backend_cmd.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/cli_commands/inspire_cmd.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/cli_commands/models_cmd.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/client.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/config.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/config_data/default.toml +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/core/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/core/formats.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/core/jobs.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/core/layout.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/generator.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/history.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/jsonstore.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/models.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/paths.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/prompts.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/transport/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_music/tui.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_podcast/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_podcast/feed.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_podcast/plugin.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_podcast/script.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/paths.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/plugin.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/stub.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_video/worker.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/cli/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/cli/engines_cmd.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/cli/models_cmd.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/cli/profiles.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/config/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/config/settings.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/core/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/core/model_manager.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/core/profiles.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/core/registry.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/core/types.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/devices.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/doctor.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/__init__.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/chatterbox.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/moss.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/piper.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/qwen3.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/stub.py +0 -0
- {aioli_cli-0.1.45 → aioli_cli-0.1.48}/src/aioli_voice/engines/xtts.py +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.venv/
|
|
4
|
+
|
|
5
|
+
# caches de herramientas (I6): un `git add -A` no debe commitearlas
|
|
6
|
+
.mypy_cache/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.ruff_cache/
|
|
9
|
+
|
|
10
|
+
# cobertura (I4): artefactos del run, se regeneran
|
|
11
|
+
.coverage
|
|
12
|
+
coverage.xml
|
|
13
|
+
|
|
14
|
+
# web
|
|
15
|
+
web/node_modules/
|
|
16
|
+
web/dist/
|
|
17
|
+
web/.astro/
|
|
18
|
+
|
|
19
|
+
dist/
|
|
20
|
+
.kaudit/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: aioli-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.48
|
|
4
4
|
Summary: aioli — local-first AI media suite CLI (images, video, music, voice, podcast)
|
|
5
5
|
Author: aioli contributors
|
|
6
6
|
License: MIT
|
|
@@ -57,10 +57,10 @@ Description-Content-Type: text/markdown
|
|
|
57
57
|
|
|
58
58
|
| Plugin | Produces | Example |
|
|
59
59
|
| --- | --- | --- |
|
|
60
|
-
| 🎙️ `voice` | Cloned or synthetic voice as WAV (native Spanish with chatterbox, free CPU drafts with piper) | `aioli voice
|
|
61
|
-
| 🎵 `music` | Full song (vocals + instruments) from a style and your lyrics — it sings in Spanish | `aioli music
|
|
62
|
-
| 🖼️ `image` | Image from text, editing, inpainting or character reference (~9 s with FLUX-klein-4b) | `aioli image
|
|
63
|
-
| 🎬 `video` | MP4 clip with synced audio from text or image | `aioli video
|
|
60
|
+
| 🎙️ `voice` | Cloned or synthetic voice as WAV (native Spanish with chatterbox, free CPU drafts with piper) | `aioli voice "Hola mundo" --profile vega -o hola.wav` |
|
|
61
|
+
| 🎵 `music` | Full song (vocals + instruments) from a style and your lyrics — it sings in Spanish | `aioli music --preset reggae-consciente -l my-lyrics.txt -o track.mp3` |
|
|
62
|
+
| 🖼️ `image` | Image from text, editing, inpainting or character reference (~9 s with FLUX-klein-4b) | `aioli image "a robot garlic"` |
|
|
63
|
+
| 🎬 `video` | MP4 clip with synced audio from text or image | `aioli video "a robot garlic dancing" --frames 81 -o ajo.mp4` |
|
|
64
64
|
| 🎧 `master` | Audio finishing with ffmpeg: mix, ducking, denoise, `-16 LUFS` | `aioli master loudnorm mix.wav -o final.wav` |
|
|
65
65
|
| 📻 `podcast` | MP3 episode + show notes from a script (voices + music bed + pauses) | `aioli podcast episode script.md -o ./ep1` |
|
|
66
66
|
|
|
@@ -69,7 +69,7 @@ with these commands. No accounts, no subscription.
|
|
|
69
69
|
|
|
70
70
|
## How it works
|
|
71
71
|
|
|
72
|
-
1. `aioli
|
|
72
|
+
1. `aioli install` inspects your machine and tells you what fits your GPU.
|
|
73
73
|
2. `aioli models download` fetches verified weights (sha256, resumable)
|
|
74
74
|
into `~/.local/share/aioli` (or wherever `AIOLI_MODELS_DIR` points).
|
|
75
75
|
3. You generate locally: not a byte leaves your machine. No accounts, no
|
|
@@ -79,15 +79,16 @@ with these commands. No accounts, no subscription.
|
|
|
79
79
|
## Install
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
|
-
curl -fsSL https://aioli.es/install.sh | sh # installs uv+ffmpeg if missing → doctor → setup → status
|
|
83
|
-
# …or truly by hand (needs `uv`, Python ≥3.12 and `ffmpeg`):
|
|
84
|
-
uv tool install aioli-cli #
|
|
85
|
-
aioli setup
|
|
86
|
-
aioli doctor
|
|
82
|
+
curl -fsSL https://aioli.es/install.sh | sh # installs uv+ffmpeg if missing → doctor → setup → status (setup = vía compat del instalador; equivale a `aioli install`)
|
|
83
|
+
# …or truly by hand (needs `uv`, Python ≥3.12 and `ffmpeg`) — two commands, no extras:
|
|
84
|
+
uv tool install aioli-cli # the CLI only (base dist, sin extras)
|
|
85
|
+
aioli setup # usage screen: tick what you want; the assistant installs piper/kokoro and downloads only that
|
|
86
|
+
aioli doctor # preflight: CUDA, ffmpeg, models, VRAM
|
|
87
|
+
# advanced alternative: `uv tool install "aioli-cli[voice-piper,music-storage]"` still works; torch worlds stay manual (`--with`, see plugins/voice/README.md)
|
|
87
88
|
```
|
|
88
89
|
|
|
89
90
|
For top-tier image and video (Flux, LTX), accept their license on
|
|
90
|
-
huggingface.co and export `HF_TOKEN` (read-only token) before
|
|
91
|
+
huggingface.co and export `HF_TOKEN` (read-only token) before install.
|
|
91
92
|
|
|
92
93
|
> 🔒 Paranoid (good): the installer lives in the repo's `install.sh`.
|
|
93
94
|
> It only uses the network for `astral.sh` (uv), GitHub and HuggingFace.
|
|
@@ -104,27 +105,31 @@ huggingface.co and export `HF_TOKEN` (read-only token) before `setup`.
|
|
|
104
105
|
| Disk | 15 GB (one plugin) | 100 GB (full set ≈ 60 GB) |
|
|
105
106
|
| Account | — | free HuggingFace (for Flux and LTX, licensed) |
|
|
106
107
|
|
|
107
|
-
`aioli
|
|
108
|
+
`aioli install` detects your machine (tier `patata/modesta/capaz/bicha` —
|
|
108
109
|
yes, potato to beast) and only downloads what fits. Weights are sha256
|
|
109
110
|
verified and resume if your connection drops.
|
|
110
111
|
|
|
111
112
|
## Usage
|
|
112
113
|
|
|
114
|
+
Camino feliz: `aioli install` → `aioli <plugin> "texto"` → `aioli doctor`
|
|
115
|
+
(solo si algo falla). Per-model recipes live in `docs/USAGE.md`.
|
|
116
|
+
|
|
113
117
|
```bash
|
|
114
118
|
# image: text → PNG (editing, inpainting and reference available)
|
|
115
|
-
aioli image
|
|
119
|
+
aioli image "a lighthouse in the fog"
|
|
120
|
+
aioli image "a lighthouse in the fog" -m z-image-turbo -o faro.png
|
|
116
121
|
|
|
117
122
|
# music: style + your lyrics → full song
|
|
118
|
-
aioli music
|
|
123
|
+
aioli music "cheerful rumba" -l my-lyrics.txt -o track.mp3
|
|
119
124
|
aioli music generate --preset reggae-consciente -l my-lyrics.txt -o track.mp3
|
|
120
125
|
|
|
121
126
|
# voice: create profile, add a sample with its transcript, generate
|
|
122
127
|
aioli voice profiles create vega --language es
|
|
123
128
|
aioli voice profiles add-sample vega ref.wav -t "exact audio transcript"
|
|
124
|
-
aioli voice
|
|
129
|
+
aioli voice "Hola mundo" --profile vega --engine chatterbox -o hola.wav
|
|
125
130
|
|
|
126
131
|
# video: text or image → clip with audio
|
|
127
|
-
aioli video
|
|
132
|
+
aioli video "a robot garlic dancing" --frames 81 -o ajo.mp4
|
|
128
133
|
|
|
129
134
|
# podcast: script with [VOICES], [MUSIC:] and [PAUSE:] → episode + notes
|
|
130
135
|
aioli podcast episode script.md -o ./ep1
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
|
|
26
26
|
| Plugin | Produces | Example |
|
|
27
27
|
| --- | --- | --- |
|
|
28
|
-
| 🎙️ `voice` | Cloned or synthetic voice as WAV (native Spanish with chatterbox, free CPU drafts with piper) | `aioli voice
|
|
29
|
-
| 🎵 `music` | Full song (vocals + instruments) from a style and your lyrics — it sings in Spanish | `aioli music
|
|
30
|
-
| 🖼️ `image` | Image from text, editing, inpainting or character reference (~9 s with FLUX-klein-4b) | `aioli image
|
|
31
|
-
| 🎬 `video` | MP4 clip with synced audio from text or image | `aioli video
|
|
28
|
+
| 🎙️ `voice` | Cloned or synthetic voice as WAV (native Spanish with chatterbox, free CPU drafts with piper) | `aioli voice "Hola mundo" --profile vega -o hola.wav` |
|
|
29
|
+
| 🎵 `music` | Full song (vocals + instruments) from a style and your lyrics — it sings in Spanish | `aioli music --preset reggae-consciente -l my-lyrics.txt -o track.mp3` |
|
|
30
|
+
| 🖼️ `image` | Image from text, editing, inpainting or character reference (~9 s with FLUX-klein-4b) | `aioli image "a robot garlic"` |
|
|
31
|
+
| 🎬 `video` | MP4 clip with synced audio from text or image | `aioli video "a robot garlic dancing" --frames 81 -o ajo.mp4` |
|
|
32
32
|
| 🎧 `master` | Audio finishing with ffmpeg: mix, ducking, denoise, `-16 LUFS` | `aioli master loudnorm mix.wav -o final.wav` |
|
|
33
33
|
| 📻 `podcast` | MP3 episode + show notes from a script (voices + music bed + pauses) | `aioli podcast episode script.md -o ./ep1` |
|
|
34
34
|
|
|
@@ -37,7 +37,7 @@ with these commands. No accounts, no subscription.
|
|
|
37
37
|
|
|
38
38
|
## How it works
|
|
39
39
|
|
|
40
|
-
1. `aioli
|
|
40
|
+
1. `aioli install` inspects your machine and tells you what fits your GPU.
|
|
41
41
|
2. `aioli models download` fetches verified weights (sha256, resumable)
|
|
42
42
|
into `~/.local/share/aioli` (or wherever `AIOLI_MODELS_DIR` points).
|
|
43
43
|
3. You generate locally: not a byte leaves your machine. No accounts, no
|
|
@@ -47,15 +47,16 @@ with these commands. No accounts, no subscription.
|
|
|
47
47
|
## Install
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
|
-
curl -fsSL https://aioli.es/install.sh | sh # installs uv+ffmpeg if missing → doctor → setup → status
|
|
51
|
-
# …or truly by hand (needs `uv`, Python ≥3.12 and `ffmpeg`):
|
|
52
|
-
uv tool install aioli-cli #
|
|
53
|
-
aioli setup
|
|
54
|
-
aioli doctor
|
|
50
|
+
curl -fsSL https://aioli.es/install.sh | sh # installs uv+ffmpeg if missing → doctor → setup → status (setup = vía compat del instalador; equivale a `aioli install`)
|
|
51
|
+
# …or truly by hand (needs `uv`, Python ≥3.12 and `ffmpeg`) — two commands, no extras:
|
|
52
|
+
uv tool install aioli-cli # the CLI only (base dist, sin extras)
|
|
53
|
+
aioli setup # usage screen: tick what you want; the assistant installs piper/kokoro and downloads only that
|
|
54
|
+
aioli doctor # preflight: CUDA, ffmpeg, models, VRAM
|
|
55
|
+
# advanced alternative: `uv tool install "aioli-cli[voice-piper,music-storage]"` still works; torch worlds stay manual (`--with`, see plugins/voice/README.md)
|
|
55
56
|
```
|
|
56
57
|
|
|
57
58
|
For top-tier image and video (Flux, LTX), accept their license on
|
|
58
|
-
huggingface.co and export `HF_TOKEN` (read-only token) before
|
|
59
|
+
huggingface.co and export `HF_TOKEN` (read-only token) before install.
|
|
59
60
|
|
|
60
61
|
> 🔒 Paranoid (good): the installer lives in the repo's `install.sh`.
|
|
61
62
|
> It only uses the network for `astral.sh` (uv), GitHub and HuggingFace.
|
|
@@ -72,27 +73,31 @@ huggingface.co and export `HF_TOKEN` (read-only token) before `setup`.
|
|
|
72
73
|
| Disk | 15 GB (one plugin) | 100 GB (full set ≈ 60 GB) |
|
|
73
74
|
| Account | — | free HuggingFace (for Flux and LTX, licensed) |
|
|
74
75
|
|
|
75
|
-
`aioli
|
|
76
|
+
`aioli install` detects your machine (tier `patata/modesta/capaz/bicha` —
|
|
76
77
|
yes, potato to beast) and only downloads what fits. Weights are sha256
|
|
77
78
|
verified and resume if your connection drops.
|
|
78
79
|
|
|
79
80
|
## Usage
|
|
80
81
|
|
|
82
|
+
Camino feliz: `aioli install` → `aioli <plugin> "texto"` → `aioli doctor`
|
|
83
|
+
(solo si algo falla). Per-model recipes live in `docs/USAGE.md`.
|
|
84
|
+
|
|
81
85
|
```bash
|
|
82
86
|
# image: text → PNG (editing, inpainting and reference available)
|
|
83
|
-
aioli image
|
|
87
|
+
aioli image "a lighthouse in the fog"
|
|
88
|
+
aioli image "a lighthouse in the fog" -m z-image-turbo -o faro.png
|
|
84
89
|
|
|
85
90
|
# music: style + your lyrics → full song
|
|
86
|
-
aioli music
|
|
91
|
+
aioli music "cheerful rumba" -l my-lyrics.txt -o track.mp3
|
|
87
92
|
aioli music generate --preset reggae-consciente -l my-lyrics.txt -o track.mp3
|
|
88
93
|
|
|
89
94
|
# voice: create profile, add a sample with its transcript, generate
|
|
90
95
|
aioli voice profiles create vega --language es
|
|
91
96
|
aioli voice profiles add-sample vega ref.wav -t "exact audio transcript"
|
|
92
|
-
aioli voice
|
|
97
|
+
aioli voice "Hola mundo" --profile vega --engine chatterbox -o hola.wav
|
|
93
98
|
|
|
94
99
|
# video: text or image → clip with audio
|
|
95
|
-
aioli video
|
|
100
|
+
aioli video "a robot garlic dancing" --frames 81 -o ajo.mp4
|
|
96
101
|
|
|
97
102
|
# podcast: script with [VOICES], [MUSIC:] and [PAUSE:] → episode + notes
|
|
98
103
|
aioli podcast episode script.md -o ./ep1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "aioli-cli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.48"
|
|
4
4
|
description = "aioli — local-first AI media suite CLI (images, video, music, voice, podcast)"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -100,6 +100,12 @@ only-include = [
|
|
|
100
100
|
"LICENSE",
|
|
101
101
|
]
|
|
102
102
|
|
|
103
|
+
# Gate de tipos canónico del repo: `mypy src` (los 8 paquetes del wheel único,
|
|
104
|
+
# 111 ficheros en verde). `libs/*` y `plugins/*` no aportan código (ver ADR-005),
|
|
105
|
+
# así que un typecheck por miembro sería un falso scope. Lo consume wave-gate.
|
|
106
|
+
[tool.wave-gate]
|
|
107
|
+
typecheck = "mypy src"
|
|
108
|
+
|
|
103
109
|
[tool.pytest.ini_options]
|
|
104
110
|
pythonpath = ["src"]
|
|
105
111
|
testpaths = [
|
|
@@ -111,7 +117,11 @@ testpaths = [
|
|
|
111
117
|
"plugins/podcast/tests",
|
|
112
118
|
"plugins/master/tests",
|
|
113
119
|
]
|
|
114
|
-
|
|
120
|
+
# I4 (2026-10-05, wave-7/T28): cobertura MEDIDA en el run normal (pytest-cov,
|
|
121
|
+
# dev dep). Sin `fail-under` ni exclusiones: medir no es un gate, y un umbral
|
|
122
|
+
# inventado sin baseline sería ruido. Regresión de config:
|
|
123
|
+
# `libs/contract/tests/test_bootstrap.py::TestCoverageConfig`.
|
|
124
|
+
addopts = "-q --cov=src --cov-report=term-missing --cov-report=xml"
|
|
115
125
|
# Markers: "network" sube a upstream real (gasta red y disco). Opt-in via
|
|
116
126
|
# AIOLI_NET_TESTS=1, lo activa el job smoke-bundles de release.yml.
|
|
117
127
|
markers = [
|
|
@@ -121,6 +131,7 @@ markers = [
|
|
|
121
131
|
[dependency-groups]
|
|
122
132
|
dev = [
|
|
123
133
|
"pytest>=8.0",
|
|
134
|
+
"pytest-cov>=7.0", # I4: cobertura del run normal (term-missing + xml)
|
|
124
135
|
"pillow>=10.0", # solo tests (stubs de imagen); nunca en dependencies
|
|
125
136
|
# H0.4: tooling de CI pineado aqui (no en `uvx` run-steps) para que
|
|
126
137
|
# dependabot lo renueve: no ve herramientas invocadas con `uvx` en los
|
|
@@ -161,15 +172,18 @@ ignore_missing_imports = true
|
|
|
161
172
|
module = ["soundfile", "soundfile.*", "tqdm"]
|
|
162
173
|
ignore_missing_imports = true
|
|
163
174
|
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
#
|
|
168
|
-
#
|
|
169
|
-
#
|
|
170
|
-
#
|
|
175
|
+
# I3 (2026-10-05, wave-7/T27): los paquetes PROPIOS (`aioli_*`) salen de aquí.
|
|
176
|
+
# Estaban por el falso positivo F-10 (mypy sin venv no resolvía `src/`), pero
|
|
177
|
+
# `ignore_missing_imports` sobre un paquete propio silencia justo lo que debe
|
|
178
|
+
# fallar: un import roto de `aioli_contract`/`aioli_cli`/... pasaba verde.
|
|
179
|
+
# `mypy_path = "src"` + `explicit_package_bases` ya resuelven los paquetes
|
|
180
|
+
# propios con la config leída desde la raíz, que es como lo ejecuta wave-gate y
|
|
181
|
+
# el job `test` de release.yml. Regresión:
|
|
182
|
+
# `libs/contract/tests/test_models_import.py::TestOwnImports`.
|
|
183
|
+
# pytest (dev dep) sí sigue fuera del venv en algunos lenses: ese override se
|
|
184
|
+
# queda.
|
|
171
185
|
[[tool.mypy.overrides]]
|
|
172
|
-
module = ["pytest", "pytest.*"
|
|
186
|
+
module = ["pytest", "pytest.*"]
|
|
173
187
|
ignore_missing_imports = true
|
|
174
188
|
|
|
175
189
|
# DEBT: aioli_music.core.jobs imports aioli_music.core.storage, which does not
|