refactor: _shared.py vira subpacote, um módulo por papel

Eram 882 linhas de seis papéis sem relação, sob um nome que só dizia
"compartilhado" — o depósito onde tudo que servia a mais de um handler
acabava caindo.

    media       316   transcrição em cache, corte por fala, relatório
    paths       206   sandbox, limites, caminho de saída
    project     116   abrir projeto, preparar modifier/generator
    captions    112   SRT, VTT, listas com timestamp
    detection    99   flash frames, buracos, duplicados
    formatting   86   tabelas e relatórios dos handlers

O __init__ reexporta os 46 nomes, então os treze pontos que importam daqui
não mudaram.

_transcript_cut_report saiu de formatting para media: ele precisa do hint de
instalação e do _text_result, ou seja, é relatório de transcrição e não
formatação genérica — mover foi mais honesto que cruzar imports entre os
dois módulos.

Quatro testes patchavam `server_tools._shared.transcribe`; o nome agora é
ligado por _shared/media.py, então o patch passou a apontar para lá — mesmo
padrão da experiência #23.

Lint zerado, 1454 testes passando.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
João Henrique
2026-08-19 22:35:02 -04:00
co-authored by Claude Opus 5
parent 368bb62706
commit ffaebb3f72
12 changed files with 1068 additions and 891 deletions
+4 -4
View File
@@ -43,7 +43,7 @@ def wav(tmp_path):
@pytest.fixture
def patched_analysis(monkeypatch):
"""Make the tool's transcription + librosa extractors deterministic."""
import server_tools._shared as _shared_mod
import server_tools._shared.media as _shared_mod
import server_tools.voice as server_mod
monkeypatch.setattr(_shared_mod, "transcribe", lambda *a, **k: _FAKE_TRANSCRIPT)
@@ -111,7 +111,7 @@ class TestAnalyzeVoiceFeaturesHandler:
assert "emphasis_weights" in data["config"]
async def test_empty_transcript_reports_instead_of_crashing(self, wav, monkeypatch):
import server_tools._shared as _shared_mod
import server_tools._shared.media as _shared_mod
import server_tools.voice as server_mod
from server import handle_analyze_voice_features
@@ -123,7 +123,7 @@ class TestAnalyzeVoiceFeaturesHandler:
assert "no words" in result[0].text.lower()
async def test_untranscribable_media_reports_install_hint(self, wav, monkeypatch):
import server_tools._shared as _shared_mod
import server_tools._shared.media as _shared_mod
import server_tools.voice as server_mod
from server import handle_analyze_voice_features
@@ -133,7 +133,7 @@ class TestAnalyzeVoiceFeaturesHandler:
assert "faster-whisper" in result[0].text
async def test_missing_pitch_track_degrades_without_crashing(self, wav, monkeypatch):
import server_tools._shared as _shared_mod
import server_tools._shared.media as _shared_mod
import server_tools.voice as server_mod
from server import handle_analyze_voice_features