Releases: CristianRojas-SoftwareEngineer/TTS-Sidecar
Release list
v0.6.0
[0.6.0] — 2026-07-11
Cierra la última brecha accionable de paridad de experiencia entre los 3 SO
registrada en docs/PARITY.md: la de desinstalación en un comando. Con ella,
tts-sidecar setup --uninstall deja de ser solo-Linux y pasa a ser un comando
único en los tres SO (dispatch por SO sobre un contrato compartido: datos → PATH
→ binario, con cancelación atómica y guard de canal nativo). MINOR: capacidad
nueva en macOS y Windows, más un cambio de comportamiento deliberado en Linux.
Solo la brecha de firma de código (SmartScreen/Gatekeeper, binarios sin firmar)
queda diferida al goal a largo plazo.
Añadido
setup --uninstallen macOS (_uninstall_macos): desinstalación de un
comando que encadenacleanup --all, quita el symlink per-user de
~/.local/biny borra el.app(localizado desdesys.executablecon
resolve(); cubre~/Applications,/Applicationsy el Cask con una sola
expresión, con guard de sufijo.app). Si la instalación proviene de Homebrew
(metadata del Caskroom), aborta sin borrar nada y remite abrew uninstall --cask --zap tts-sidecarpara no dejar el Caskroom inconsistente.setup --uninstallen Windows (_uninstall_windows): valida primero el
QuietUninstallStringdel registro (HKCU, clave{AppId}_is1) sin efectos,
borra los datos en proceso concleanup --ally delega el binario y la
reversión del PATH al desinstalador de Inno, lanzado desacoplado con
subprocess.Popen(el SO mantiene el lock del.exe). El payload--json
atestigua las rutas de datos enremovedy el directorio de instalación en el
campo aditivodelegated.- Guard de canal nativo (
is_frozen) ensetup --uninstall, común a los
tres SO: desde fuente o desde una instalación pip/uv, aborta remitiendo apip uninstall tts-sidecaren lugar de operar sobre rutas que no le pertenecen.
Cambiado
- Reorden de la rama Linux de
setup --uninstallal orden unificado del
contrato compartido (cleanup --all→ symlink → directorio de instalación, en
vez de symlink → directorio → cleanup). Habilita la cancelación atómica:
cancelar la confirmación del cleanup aborta la desinstalación sin borrar nada
(salida 0), imposible con el orden anterior (el binario caía antes de la
pregunta). Además el uninstall borra ahora el directorio raíz de datos
(data_root()) si queda vacío tras el cleanup. - Payload
--jsondesetup --uninstall:removedincluye ahora las rutas
de datos delcleanupencadenado (corrección de una omisión de la rama Linux)
y eldata_root()si se eliminó. En Windows se añade el campodelegated
(directorio de instalación, borrado por Inno tras la salida del proceso).
Ambos son cambios aditivos:schema_versionno cambia.
v0.5.0
[0.5.0] — 2026-07-10
Cierra las brechas de paridad de experiencia entre los 3 SO registradas en
docs/PARITY.md: iguala macOS y Linux con la experiencia objetivo de Windows
(instalación de una línea sin admin, actualización sin residuo, desinstalación
con residuo cero). MINOR: añade capacidades y cambia el comportamiento de
instalación en macOS. Solo la brecha 4 (Gatekeeper, cuyo fondo es la firma de
código) queda diferida al goal a largo plazo.
Añadido
- Instalador macOS de una línea (
install-macos.sh,curl | sh): vía sin
Homebrew nisudo, homóloga ainstall.sh. Descarga el.dmgde arm64 y
SHA256SUMS.txt, verifica el checksum conshasum -a 256 -c(aborta si no
coincide), monta conhdiutil, copia el.appa~/Applicationscon
ditto, limpia la cuarentena de Gatekeeper conxattr, crea el symlink
per-user en~/.local/bin(con aviso de PATH) y encadenasetup. Guard de
arquitectura arm64 (Mac Intel no soportado). Smoke-testbatsen el job CI
test-installer-macos(executor macOS) como puerta de los 4 builds. - Desinstalador Linux de un paso (
tts-sidecar setup --uninstall): quita
el symlink de PATH, borra~/.local/opt/tts-sidecar/y encadenacleanup --all(con confirmación;--yesla omite). Mutuamente excluyente con
--remove-path/--force-update, con guard de SO y contrato--json
(requiere--yes). Reemplaza los tres pasos manuales anteriores.
Cambiado
- Scripts
.commanddel.dmgsinsudo: la instalación y desinstalación
incluidas en el.dmgde macOS crean/eliminan el symlink per-user en
~/.local/binen lugar de/usr/local/binconsudo. Ninguna vía de
instalación del proyecto pide ya la contraseña de administrador. Nota de
transición: quien tenga un symlink legado en/usr/local/bin(de una
versión anterior a 0.5.0) verá en el script de desinstalación la instrucción
para quitarlo (sudo rm /usr/local/bin/tts-sidecar). install.shlimpia los AppImages anteriores: tras instalar y dar
permisos al AppImage nuevo, elimina lostts-sidecar-*.AppImageprevios de
~/.local/opt/tts-sidecar/, que antes se acumulaban (~1-2 GB por versión).
Re-ejecutar el one-liner es ahora la vía de actualización limpia de Linux.
Corregido
zapdel Cask completo: la stanzazap trash:del Cask de Homebrew ahora
lista los dos repos del modelo en la caché de HuggingFace (el multilingüe
Chatterbox-Multilingual-es-mx-latamy el basechatterboxdel Voice
Encoder); antes omitía el segundo, dejando cientos de MB de residuo a quien
desinstalara conbrew uninstall --zap. Se propaga al tap con este release
víapublish-metadata.
v0.4.0
[0.4.0] — 2026-07-10
Extiende la instalación auto-hospedada de una línea a Windows y migra el
instalador Inno Setup a per-user, sin tocar el contrato del CLI (códigos de
salida, esquemas --json). MINOR: cambia el comportamiento de instalación
en Windows.
Añadido
- Instalador Windows de una línea (
install.ps1,irm | iex): resuelve
el release más reciente, descarga el instalador x86_64 ySHA256SUMS.txt,
verifica el checksum SHA-256 antes de instalar (aborta si no coincide),
instala en silencio sin UAC y ejecutatts-sidecar setup. La descarga por
CLI no aplica el Mark-of-the-Web, así que no dispara SmartScreen (detalle
endocs/SELF-HOSTED-INSTALL.mdySECURITY.md). Smoke-test Pester en CI
(test-installer-windows) como puerta de los 4 builds.
Cambiado
- Instalador de Windows per-user: Inno Setup pasa de per-machine a
per-user —PrivilegesRequired=lowest(sin prompt de UAC), instalación en
%LOCALAPPDATA%\Programs\tts-sidecar(antes Program Files) y PATH de
usuario enHKCU\Environment(antes HKLM), incluida su reversión al
desinstalar. Nota de migración: si tienes instalada una versión
per-machine (anterior a 0.4.0), desinstálala primero desde el Panel de
control (con admin) antes de instalar 0.4.0+; instalar la per-user encima
puede dejar dos instalaciones y PATH duplicado.
v0.3.0
[0.3.0] — 2026-07-10
Extiende el canal nativo con instalación auto-hospedada por SO y reduce los
falsos positivos de antivirus en los binarios PyInstaller, sin tocar el
contrato del CLI (códigos de salida, esquemas --json) ni los canales
existentes (nativo/PyPI).
Añadido
- Instalador Linux de una línea (
install.sh): resuelve el release más
reciente, elige el.AppImagepor arquitectura (uname -m), verifica el
checksum SHA-256 contraSHA256SUMS.txtantes de instalar, integra el PATH
vía la variableAPPIMAGEy ejecutasetup. Documentado enREADME.mdy
USAGE.mdcon su desinstalación limpia de 3 pasos. - Cask de Homebrew propio (
homebrew-tts-sidecar):brew install --cask tts-sidecarinstala desde el.dmgdel release;publish-metadataen CI
reescribe el Cask con la versión y elsha256del.dmgen cada release
(idempotente). Verdocs/RELEASING.mdydocs/DISTRIBUTION.md. - Runbook de reporte de falso positivo a Windows Defender Security
Intelligence (WDSI) enSECURITY.md, acotado a la detección de Defender
Antivirus (no afecta SmartScreen).
Cambiado
- Endurecimiento del build PyInstaller:
--noupxen los flags compartidos
y metadata PE (--version-file) en el.exede Windows, para mitigar las
heurísticas de antivirus sobre el patrón de empaquetado. Cubierto por tests.
v0.2.1
[0.2.1] — 2026-07-08
Corrige la instalación vía uv tool install tts-sidecar: quedaba rota por un
conflicto de resolución de dependencias entre numpy y numba (transitiva de
librosa/chatterbox-tts).
Corregido
uv tool install tts-sidecarfallaba al intentar compilar
llvmlite==0.36.0desde fuente en Python 3.13 (RuntimeError: Cannot install on Python version 3.13.14; only versions >=3.6,<3.10 are supported). Causa:chatterbox-ttsdeclaranumpy>=2.0.0sin tope
superior para Python ≥3.13, mientras quenumba(dependencia transitiva vía
librosa) exigenumpy<2.5. El resolvedor deuvfijaba primero la
versión más reciente denumpy(sin tope) y, al no poder satisfacer el tope
denumba, retrocedía sobrenumbahasta versiones sin soporte para Python
3.13, en vez de retroceder sobrenumpy.pipno caía en esta trampa por
las heurísticas de su propio resolvedor, por lo que el smoke test de CI
(que usapip install) no lo detectó. Fix: se fija explícitamente
numpy<2.5como dependencia directa enpyproject.toml, acotando el rango
antes de que cualquier resolvedor tenga que elegir entrenumpyynumba.
v0.2.0
[0.2.0] — 2026-07-08
Añade un segundo canal de distribución (PyPI / uv tool install / pipx)
junto al canal nativo de binarios PyInstaller existente, sin afectar su
funcionamiento. Requirió reestructurar la ubicación de las voces de fábrica y
el modelo de rutas para que sean válidos en los tres modos de ejecución
(fuente, pip-installed, congelado) sin bifurcaciones. Registra además la
estrategia de firma de código (SignPath + notarización Apple) como compromiso
de roadmap en docs/GOAL.md.
Añadido
- Canal de distribución PyPI:
uv tool install tts-sidecar/pipx install tts-sidecarinstala el CLI completo, incluida la vozdefault.
Publicación automática en cada tagv*vía el jobpublish-pypide CI, en
paralelo a los cuatro builds nativos. Documentado en el nuevo
docs/DISTRIBUTION.md, con la matriz de trade-offs frente al canal nativo
y el registro de la decisión de mantener ambos canales en paralelo. src/tts_sidecar/bootstrap.py: consolida en una única función
idempotente (apply()) la supresión de warnings, las variables de entorno y
el mock depkg_resourcesque antes solo vivían enbin/tts-sidecar,
duplicados parcialmente endaemon/run.py. Corre igual desde el entry point
de pip,bin/tts-sidecar,python -m tts_sidecary el daemon.src/tts_sidecar/__main__.py: habilitapython -m tts_sidecarcomo
vía de invocación adicional.
Cambiado
- Voces de fábrica reubicadas a
src/tts_sidecar/voices/(antesvoices/
en la raíz del repo), para que setuptools pueda empaquetarlas en el wheel
(package-data); el bundle PyInstaller (--add-data) se actualizó al mismo
origen. - Modelo de rutas uniforme (
paths.py):bundled_voices_dir()resuelve
siempre relativa al paquete (sin distinguir fuente/congelado) ydata_root()
devuelve siempre el user-data-dir por SO, incluso en modo fuente (antes
caía dentro del propio checkout). pyproject.tomlpublicable: entry pointtts-sidecar = "tts_sidecar.cli:main",
versión dinámica (dynamic = ["version"]) resuelta desde
tts_sidecar.__version__como fuente única, metadata de PyPI completa
(readme,urls,classifiers,keywords) ypackage-datapara las
voces de fábrica.
v0.1.1
[0.1.1] — 2026-07-07
Ciclo perfectivo que corrige los 12 hallazgos Menores y el residuo WARNING-01
identificados durante la revisión final del release 0.1.0, más el ciclo
correctivo de la auditoría de production-readiness: cierra la única grieta
funcional (el release gate del pin de revisiones en la carga del engine) y siete
Menores (gate de daemon serve, identidad del health check, sandbox acotado del
daemon, exactitud documental y procedencia del lockfile). Todos los cambios
de contrato son aditivos: los códigos de salida existentes no cambian y
schema_version permanece en "1".
Añadido
--jsonen los cuatro comandos de escritura (R-03):voice add
({name, reference, speech}),voice remove({name, removed}),setup
({model, already_cached, downloaded, cache_dir}, con variante para
--remove-path) ycleanup({removed, dry_run}). El contrato programático
queda simétrico: ningún comando obliga a parsear texto.cleanup --json
exige--yeso--dry-run(exit 4 sin ellos) y envía sus listados
informativos a stderr.- Referencia de esquemas
--jsonenUSAGE.md(R-04): las claves de los
nueve payloads (tipo y significado) declaradas por escrito como parte del
contrato, sin necesidad de ingeniería inversa. - Revisión fijada del modelo por release (R-15):
setupdescarga ambos
repos de HuggingFace conrevision=(commit hash auditado, constantes
MODEL_REVISIONS/BASE_MODEL_REVISIONenmodel_cache.py) y la detección
de caché valida el snapshot de esa revisión en ambos repos (ciclo posterior
cerró el residuoWARNING-01del repo base); el bump del pin es un paso del
runbook de release (docs/RELEASING.md) y su alcance está descrito en
SECURITY.md. - Plantillas de Issue/PR en
.github/(R-12): formularios de bug (versión,
SO, comando reproducible, salida) y de propuesta,blank_issues_enabled: falsecon la vía de seguridad señalizada, y checklist de PR alineado a
CONTRIBUTING.md.
Cambiado
-
Documentación del bloqueo SmartScreen/Gatekeeper ampliada:
README.md,
USAGE.md,SECURITY.mdydocs/BUILD.mdexplican por qué el sistema
bloquea el primer arranque (binario sin firma + sin reputación por ser cada
release un archivo nuevo), que no indica malware, cómo proceder paso a paso
(incluido el bloqueo del navegador y la cuarentena de antivirus de terceros,
siempre tras verificar el SHA-256) y la ruta prevista de firma de código vía
SignPath Foundation (gratuita para proyectos open source). -
daemon stophonesto durante la ventana de arranque (R-05): detecta el
daemon en arranque por cmdline (sin PID file), avisa «arrancando; aún no
acepta conexiones» y termina con exit 5 en vez de reportar un éxito falso;
no mata el proceso. Documentado endocs/DAEMON-MODE.md. -
CI con imágenes fijadas por digest y pip pineado (R-14): las tres
referenciascimg/python:3.13usan@sha256:<digest>(manifest list
multi-arch) y los sietepip install --upgrade pippasaron a versión exacta.
Excepciones documentadas:brew upgrade pyenv(necesario para el parche
3.13.14; no altera el artefacto) ycreate-dmg(Homebrew no pinea).
Implicaciones y procedimiento de bump endocs/BUILD.md§Reproducibilidad. -
Exactitud documental (R-11, R-13): stack de reproducción real
(winsound/sounddevice/afplay) endocs/DESIGN.mdydocs/ARCHITECTURE.md
(antes describían pycaw-WASAPI/pyalsaaudio/AVFoundation); árboles de
estructura convoices.py,paths.pyymodel_cache.py; CI descrito como
Linux/Windows/macOS enCONTRIBUTING.md; conteo de tests actualizado a
268 endocs/GOAL.md; inventario de licencias consistente (dependencias
copyleft-compatibles mencionadas enUSAGE.md/CLAUDE.md; los runtimes
NVIDIA no van en ningún artefacto distribuido —README.mdy
THIRD-PARTY-LICENSES.md). -
El engine honra las revisiones fijadas en la carga y en las descargas de
respaldo (release gate de la auditoría de production-readiness): la
resolución de snapshot en tiempo de carga (language pack y snapshot base del
Voice Encoder) y las dos redes de seguridad de descarga (snapshot_download
del modelo,hf_hub_downloaddeve.safetensors) pasanrevision=
(MODEL_REVISIONS/BASE_MODEL_REVISION). Cierra la asimetría por la que la
detección honraba el pin pero la carga caía al fallbackrefs/main→mtime: tras
un bump futuro de revisión ya no puede producirse síntesis silenciosa con el
modelo viejo. Simétrico consetupy la detección de caché. -
daemon serveexige el modelo en caché antes de arrancar (auditoría de
production-readiness): mismo gate quedaemon start; sin modelo provisionado
falla rápido remitiendo asetup(exit 2) sin cargar el engine ni disparar la
descarga de su red de seguridad. Ningún subcomando descarga de forma implícita. -
Sandbox de audio del daemon acotado a un subdirectorio namespaced
(auditoría de production-readiness):/synthesizeacepta audio bajo los
directorios de voces (fábrica/usuario) y<tempdir>/tts-sidecar/, pero ya no
bajo el tempdir compartido general (%TEMP%//tmp), reduciendo la superficie
de temp compartido preservando el staging IPC.docs/DAEMON-MODE.mdy
USAGE.mddescriben la superficie real. -
Exactitud documental de estados, conteos y
doctor(auditoría de
production-readiness):daemon statusdocumenta los valores reales
("healthy"/"initializing", ya no"ready") en prosa y en la tabla del
esquema JSON deUSAGE.md; el ejemplo dedoctorincluye el chequeo de RAM y
el total de chequeos coherente (5); conteo de tests a 268. -
requirements-lock.txtregenerado con el comando canónico (auditoría de
production-readiness): sin el--constrainta un archivo externo al repo; su
header ya no referencia ningún override y la procedencia vuelve a ser
reproducible desdeCLAUDE.md/docs/BUILD.md. La resolución de versiones es
idéntica a la anterior; instala con--require-hashes.
Corregido
voice listante un directorio de voces ilegible (R-01): el mensaje
apunta al directorio de voces de usuario implicado en vez de remitir a
tts-sidecar setup(que no resuelve un problema de filesystem); conserva
exit 3.speak --daemon --no-daemon(R-02): los flags contradictorios producen
un error claro en stderr y exit 4 antes de cualquier trabajo, en vez de que
--daemongane en silencio.- Validación de integridad de los tres checkpoints (R-07):
is_model_cached
valida el header safetensors también des3gen_v3.safetensorsy
ve.safetensors(antes solo del T3): una descarga truncada de cualquiera se
reporta como «no cacheado» ydoctorremite asetup, en vez de reventar
con un error críptico en el primerspeak. - Fixture
mock_daemon_clientalineada con el cliente real (R-10): la
firma desynthesizecoincide conDaemonIPCClient.synthesize
(on_progressen vez de los inexistentesmodel/compute_backend). - La detección de vida del daemon valida la identidad del servicio
(auditoría de production-readiness):DaemonIPCClient.is_runningya no acepta
cualquier200en/health, sino que valida el cuerpo contraHealthResponse;
si otro servicio local ocupara el puerto 8765 y respondiera200, ya no se
confunde con un falso «daemon ya corriendo» (que derivaba en síntesis fallidas
con exit 5 difícil de atribuir).DaemonManagerdelega en el mismo chequeo. - Detección del Voice Encoder honra la revisión fijada del repo base
(WARNING-01, residuo de R-06):is_ve_cachedresuelve el snapshot del
repoResembleAI/chatterboxexclusivamente contraBASE_MODEL_REVISION(un
VE de otra revisión ya no cuenta como caché válida), simétrico con la
descarga desetupy con la rama del language pack. Cobertura nueva: caso
positivo bajoBASE_MODEL_REVISIONy caso negativo (revisión distinta) en
tests/test_engine_cache.py. Párrafo deUSAGE.mdsobre actualización
anclado al mecanismo real (revisión fijada por release + deduplicación por
blob de la caché de HF). - Decisión de validación E2E documentada (criterios 1-3, 9 de
docs/GOAL.md): la validación end-to-end de los instaladores por SO es
externa al pipeline por diseño (consume demasiada cuota de runner al cargar
el modelo y los ~2 GB de pesos en cada build). El pipeline mantiene el smoke
test automatizado del binario congelado. Fuera del pipeline: Windows la
realiza el propietario sobre su equipo local; Linux y macOS dependen de
feedback de usuarios reales. La decisión completa está endocs/GOAL.md
§"Decisión de validación E2E" ydocs/BUILD.md§"Verificación post-build".
v0.1.0
[0.1.0] — 2026-07-03
Release inaugural. Al ser la primera versión publicada, no hay base previa
respecto de la cual registrar cambios o correcciones: esta sección describe el
estado con el que nace el producto.
Añadido
- Motor de síntesis offline con Chatterbox Multilingual (alias
es-mx-latam, español latinoamericano): voz por defecto empaquetada
(default, de fábrica) y clonación de voz víavoice addcon modelo
dual-audio (reference.wavpara timbre +speech.wavpara conditioning).
El audio generado no lleva marca de agua (watermark de PerthNet desactivado
por diseño; ver «Uso ético y responsable»). - CLI multiplataforma (Windows/Linux/macOS, idéntica en los tres SO) con
los comandosspeak,voice(add/list/remove),daemon
(start/stop/restart/status/serve),devices,doctor,setup,
cleanupyversion; salidas de usuario en español. - Contrato programático para orquestadores (consumo vía
subprocess):
stdout reservado para datos y diagnóstico/progreso por stderr (UTF-8 forzado);
mapa de códigos de salida congelado —0éxito,1error genérico,2
modelo no provisionado,3voz/audio no encontrado,4entrada inválida,
5daemon inalcanzable,130interrupción (Ctrl+C, sin traceback) —;
--jsonconschema_versionen los comandos de lectura (version,
doctor,devices,voice list,daemon status). - Progreso real en vivo durante
speak: eventos de etapa (conditionals →
T3 → S3Gen → encoding → guardado) y conteo de tokens del T3 alimentan un
indicador sobre stderr (solo en TTY), en modo directo y daemon. - Modo daemon: servidor HTTP persistente en loopback (puerto fijo 8765,
sin autenticación — control de acceso delegado al SO) que mantiene el modelo
en memoria entre invocaciones;/synthesizeresponde un stream NDJSON
(progress→result/error, modelos Pydantic endaemon/protocol.py);
sandbox de rutas de audio (solo directorios de voces) con degradación
automática a modo directo o error accionable según el despacho; auto-reinicio
opcional (--autorestart,--max-retries). - Validación de entrada en
speak:--textacotado a 5000 caracteres
(exit 4 en ambas rutas, directa y daemon) con advertencia no bloqueante por
encima de 2000;--compute-backend(auto/cpu/cuda/mps) con aviso
cuando el daemon lo ignora;--outputcrea los directorios padres. - Ciclo de vida de provisión completo:
setupidempotente (chequeos de
entorno + descarga ligera víasnapshot_download, sin cargar el modelo en
RAM; incluyeve.safetensorspara que ningúnspeakposterior necesite
red), pre-chequeo de espacio en disco,--force-updatepara re-descarga
limpia, e integración de PATH en Linux/AppImage (--remove-pathla
revierte);speak/daemon startfallan rápido remitiendo asetupsin
descargas silenciosas;cleanupdesaprovisiona quirúrgicamente
(--model/--voices/--all/--dry-run, confirmación interactiva,--yes
y EOF tratado como cancelación limpia para uso programático). - Distribución por SO: instalador de Windows (Inno Setup, PATH + casilla de
setup), AppImages de Linux x86_64/aarch64 (runtime estático, sinlibfuse2;
requiere glibc ≥ 2.35, documentado con troubleshooting) y.dmgde macOS
arm64 con scripts de instalación/desinstalación yLSMinimumSystemVersion
derivada dinámicamente del toolchain. - Cadena de suministro y CI: lockfile universal con hashes
(requirements-lock.txt, instalado con--require-hashes) y lock CPU-only
de Linux x86_64 (sin el stacknvidia-*-cu12, AppImage de cientos de MB en
vez de GB); triple puerta de tests en CI (Linux/Windows/macOS nativos) que
bloquea los 4 builds; smoke test del binario congelado en cada build; SHA-256
de cada artefacto emitido en el log ySHA256SUMS.txten el Release; runbook
de publicación endocs/RELEASING.md. - Documentación y gobernanza:
USAGE.md(guía por caso de uso),
docs/DESIGN.md,docs/ARCHITECTURE.md,docs/DAEMON-MODE.md,
docs/BUILD.md,docs/RELEASING.md, sección de uso ético y responsable
(README/USAGE),CONTRIBUTING.md,SECURITY.md, esteCHANGELOG.mdy
THIRD-PARTY-LICENSES.md(inventario de licencias generado del lockfile).
Código propio bajo GPL-3.0-or-later; modelo MIT.