Transcript: ditado local para Windows e Linux. Atalho Ctrl+Shift+Space, gravação e o editor Texto transcrito com os botões Copiar e Inserir ![Tauri 2](https://img.shields.io/badge/Tauri-2-24C8DB?style=flat-square&logo=tauri&logoColor=white) ![Rust edition 2021](https://img.shields.io/badge/Rust-edition%202021-B7410E?style=flat-square&logo=rust&logoColor=white) ![TypeScript 5.9](https://img.shields.io/badge/TypeScript-5.9-3178C6?style=flat-square&logo=typescript&logoColor=white) ![Plataforma Windows e Linux](https://img.shields.io/badge/plataforma-Windows%20%C2%B7%20Linux-lightgrey?style=flat-square) ![Status protótipo](https://img.shields.io/badge/status-prot%C3%B3tipo-orange?style=flat-square) [Issues](https://git.evandro.dev.br/evandro/transcript/issues) · [Specs](docs/superpowers/specs/) · [Planos](docs/superpowers/plans/)
## O que é Transcript é um app de bandeja para Windows e Linux, feito com Tauri 2. Você aperta um atalho global, fala, e o texto transcrito localmente aparece num editor para revisão antes de ser colado no aplicativo em foco. - Alterna a gravação com o atalho global `Ctrl+Shift+Space` (evento `transcript://toggle-recording` para o frontend). - Grava o microfone em WAV (`cpal` + `hound`) na pasta de dados do app. - Transcreve chamando o sidecar `sherpa-onnx-offline` com o modelo Parakeet TDT 0.6B int8 e guarda um diagnóstico de cada tentativa (etapa, exit code, final de stdout/stderr). - Mostra o texto num editor, com os botões Copiar e Inserir. - Mantém um ícone na bandeja com o menu Mostrar app, Iniciar gravação e Sair. - Lista o catálogo de modelos com status e baixa o modelo padrão. ## Por que usar A transcrição roda na sua máquina: o comando que encerra a gravação chama o `sherpa-onnx-offline` local, sem serviço online no caminho. O texto só vai para o app em foco depois que você revisa e clica em Inserir, que copia para o clipboard e manda `Ctrl+V`. Não use ainda se você precisa de um ditado que funcione hoje: o código atual não compila (veja [Estado do projeto](#estado-do-projeto)). Também não há colagem automática no Wayland nem no macOS, e o atalho é fixo. ## Como funciona - O atalho emite um evento que o frontend escuta para iniciar ou parar a gravação. - Ao parar, `stop_recording_and_transcribe` fecha o WAV, roda o sidecar (de 1 a 4 threads) e devolve o texto num snapshot para o editor. - Só depois da revisão o botão Inserir chama `request_insert_text`, que copia o texto e tenta colar. - O código também tem adaptadores para o sidecar CrispASR (modelo GGUF legado) e para APIs compatíveis com OpenAI (padrão `http://localhost:8022/v1/audio/transcriptions`), mas nenhum comando os usa hoje. | Sistema | Inserção no app em foco | Fallback | |---|---|---| | Windows | Clipboard + `Ctrl+V` via PowerShell `SendKeys` | Se o `Ctrl+V` falhar, o texto fica copiado e uma mensagem avisa. | | Linux X11 | Clipboard + `xdotool key --clearmodifiers ctrl+v` | Sem `xdotool`, o texto fica copiado para colar à mão. | | Linux Wayland | Só copia | Cole com `Ctrl+V`. | A sessão é detectada por `XDG_SESSION_TYPE`, `WAYLAND_DISPLAY` e `DISPLAY`. | Modelo | Formato | Tamanho no catálogo | Idiomas | Uso | |---|---|---|---|---| | `sherpa-onnx-nemo-parakeet-tdt-0.6b-v2-int8` | tarball `.tar.bz2` do release `asr-models` do k2-fsa/sherpa-onnx | ~640 MB | 25 idiomas europeus, incluindo `pt` | Padrão | | `parakeet-tdt-0.6b-v3-q8_0` | GGUF `Q8_0`, repositório `cstr/parakeet-tdt-0.6b-v3-GGUF` | 745121600 bytes | `pt`, `en` | Legado, para o adaptador CrispASR | ## Início rápido | Ferramenta | Versão | Observação | |---|---|---| | Node.js + npm | 22 | Versão usada nos workflows; não há `.nvmrc` nem `engines`. | | Rust (cargo) | stable, edition 2021 | Os workflows usam `dtolnay/rust-toolchain@stable`. | | Tauri CLI | `^2.9.0` | devDependency, vem com `npm ci`. | | Linux (build) | `libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libasound2-dev` | Pacotes instalados no CI. | | Linux X11 (colar) | `xdotool` | Opcional. | | `tar` com bzip2 | qualquer | Usado por `scripts/setup-fixtures.mjs`. | ```bash git clone https://git.evandro.dev.br/evandro/transcript.git cd transcript npm ci node scripts/setup-sidecar.mjs # baixa o sherpa-onnx-offline para src-tauri/binaries/ npm run tauri:dev # app em desenvolvimento (Vite em 127.0.0.1:1420) npm run tauri:build # bundles em src-tauri/target/release/bundle/ ``` Hoje os dois comandos `tauri:*` param na compilação do Rust. O front end sozinho roda com `npm run dev`, e os testes dele com `npm test -- --run`. O modelo não vem no instalador: o app baixa para a pasta de dados (`%LOCALAPPDATA%\transcript\models` no Windows, `~/.local/share/transcript/models` no Linux) pelo comando `download_default_model_command`. As gravações ficam em `recordings/` na mesma pasta. ## Configuração Não há `.env.example` e nenhuma variável é obrigatória. | Variável | Descrição | |---|---| | `SHERPA_ONNX_SIDECAR` | Caminho do sidecar; tem prioridade sobre a pasta `binaries/` e o `PATH`. | | `SHERPA_ONNX_VERSION` | Versão do release do sherpa-onnx baixada por `setup-sidecar.mjs` (padrão `v1.12.23`). | | `SHERPA_ONNX_TRIPLE` | Target triple do sidecar (padrão: detectado via `rustc -vV`). | O método de inserção nas configurações aceita `clipboardPaste` (padrão), `keyTyping` e `manualCopy`. ## Estado do projeto Protótipo em desenvolvimento por uma pessoa. As versões divergem: `0.1.0` em `package.json` e `Cargo.toml`, `0.3.1` em `tauri.conf.json`. O que a leitura do código mostra: - **O crate Rust não compila como está:** `settings/mod.rs` usa `crate::shortcuts::DEFAULT_HOTKEY`, que não existe; `transcription/openai.rs` importa `crate::secrets`, módulo que `lib.rs` não declara; `ui_commands.rs` lê `settings.transcription.model_id`, campo que `TranscriptionSettings` não tem. - **O frontend chama comandos que não estão registrados** no `invoke_handler` de `lib.rs`: `stop_recording` (usado pelo botão Parar), `transcribe_pending`, `minimize_window`, `close_window`, `save_openai_api_key` e `clear_openai_api_key`. - **Nome do sidecar:** `setup-sidecar.mjs` grava `src-tauri/binaries/sherpa-onnx-offline-`, mas o app procura `sherpa-onnx-offline` sem o sufixo e cai no `PATH`. Até isso mudar, aponte `SHERPA_ONNX_SIDECAR` para o binário. - `keyTyping` não tem efeito: `request_insert_text` usa sempre `ClipboardPaste`. - `tauri.conf.json` não declara `bundle.externalBin` (o sidecar não vai no instalador), `bundle.resources` aponta para `resources/whisper/`, que não existe, e só `icons/icon.ico` existe dos ícones listados. whisper.cpp só aparece no spec do redesign. - O atalho `Ctrl+Shift+Space` é fixo em `shortcuts.rs`, e o item Iniciar gravação da bandeja só mostra a janela. - `ci.yml` baixa o modelo `v3-int8` (o catálogo usa `v2-int8`) e chama o teste `sherpa_onnx::tests::real_transcription_returns_known_text`, que não existe em `sherpa_onnx.rs`. Workflows em `.github/workflows/`: `ci.yml` (PR e push em `main`: typecheck, testes, build e `cargo test` no Ubuntu 22.04), `build.yml` (push em `main` e manual: bundles para Windows e Linux como artefatos) e `release.yml` (tag `v*.*.*` ou manual: publica a GitHub Release `Transcript `). Antes de abrir um PR: `npm run typecheck && npm test -- --run && cargo test --manifest-path src-tauri/Cargo.toml`. ## Licença Sem licença publicada: todos os direitos reservados. ---
Feito por Evandro Fonseca Junior · git.evandro.dev.br