| .github/workflows | ||
| .vscode | ||
| public | ||
| scripts | ||
| src | ||
| src-tauri | ||
| .editorconfig | ||
| .gitignore | ||
| .prettierrc | ||
| .release-please-manifest.json | ||
| activate_env.sh | ||
| brand.json | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| eslint.config.js | ||
| index.html | ||
| Justfile | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| release-please-config.json | ||
| setup_env.sh | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| tsconfig.node.tsbuildinfo | ||
| tsconfig.tsbuildinfo | ||
| vite.config.d.ts | ||
| vite.config.js | ||
| vite.config.ts | ||
Announcemint
Convert text to speech using AWS Polly, with presets for two-way radio voice prompts and more. Cross-platform desktop app and CLI: one prompt per line, Ogg Vorbis or in-app conversion to WAV.
App name, publisher, docs URL, and GitHub repo are set in brand.json at the project root so you can rebrand in one place (see Rebranding).
Getting the app
Prebuilt installers (Windows MSI and NSIS .exe, macOS .app, Linux AppImage) are published on the Releases page. On Windows, the NSIS installer (.exe) lets you choose per-user or system-wide install; the MSI installs per-machine. You need AWS credentials with Polly permissions before generating speech.
Features
Desktop app
- Main screen: Prompts text area (one per line), output directory, Generate Prompts button. Progress shows the current prompt name, a progress bar, and step-by-step status (Submitted to Polly → Downloading → Converting → Saving). If any destination files already exist, the app asks for overwrite confirmation before generating.
- Status indicator: Green / yellow / red dot next to Settings shows AWS auth and permission status (authenticated + Polly permissions, authenticated only, or not authenticated).
- Help: Opens the docs URL in the system browser (set in
brand.json). - About: App version (including Git SHA for dev builds), license, and project links.
Settings (full-page, expandable drawers)
- Network Proxy: Optional HTTP/HTTPS/SOCKS proxy (protocol, host, port, username, password). Test proxy checks that the app can reach the AWS API through the proxy.
- AWS Account: Credential source (AWS config file or manual keys). Config directory and profile selection; Check credentials and permissions validates auth and reports User ID, Account, ARN, Region, config file path, public IP, and whether
polly:DescribeVoicesandpolly:SynthesizeSpeechare granted. - Voice Options: Language (including system locale), engine (standard/neural), voice, output preset (e.g. OGG Vorbis, WAV: Two-Way Radio Voice Prompt). Option to remember prompt names after closing.
- Saving Prompts: Output directory and Filename Formatting (e.g. hyphens, underscores, lower/upper case).
Configuration is stored in a platform-specific user config directory (e.g. ~/.config/<publisher>/<appName>/config.json), where publisher and appName come from brand.json.
Output presets
- OGG Vorbis: Polly output as-is.
- WAV: Two-Way Radio Voice Prompt: 8 kHz, 16-bit, mono, little endian. In-app Ogg→WAV conversion (no SoX).
CLI
Same generation logic as the app. Prompts from --file or --text; output directory and optional voice, engine, preset.
# Build first (or use cargo run)
cargo build --release --manifest-path src-tauri/Cargo.toml
# Generate
./src-tauri/target/release/announcemint generate --output-dir ./out --file prompts.txt --preset "WAV: Two-Way Radio Voice Prompt"
Options: --output-dir / -o, --file / -f, --text / -t, --voice-id, --engine, --preset / -p.
Environment: ANNOUNCEMINT_OUTPUT_DIR, ANNOUNCEMINT_VOICE_ID, ANNOUNCEMINT_ENGINE, ANNOUNCEMINT_LANGUAGE_CODE, ANNOUNCEMINT_PRESET, plus standard AWS (AWS_PROFILE, AWS_REGION, etc.).
Requirements
- Node.js and npm (for the frontend and Tauri dev/build)
- Rust (for the backend and CLI)
- AWS credentials with
polly:DescribeVoicesandpolly:SynthesizeSpeech(env vars,~/.awsconfig, or manual entry in Settings)
Linux: system libraries for the GUI
The desktop app uses WebKitGTK. Install the development packages so pkg-config can find them (e.g. for just gui or npm run tauri dev).
-
Fedora / RHEL:
sudo dnf install glib2-devel webkit2gtk4.1-devel libsoup3-devel librsvg2-devel(On some Fedora versions you may need
javascriptcoregtk4.1-develif the above is not enough. If you seegio-2.0or other GLib.pcnot found, installglib2-devel. For AppImage builds,librsvg2-develis required by the linuxdeploy GTK plugin.) -
Debian / Ubuntu:
sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev
If the build still reports a missing .pc file:
-
Using Linuxbrew or Homebrew on Linux: That
pkg-configonly searches Homebrew’s prefix, so it never sees system libraries. Prepend the system pkg-config directory so the WebKit/GTK.pcfiles are found:export PKG_CONFIG_PATH="/usr/lib64/pkgconfig:$PKG_CONFIG_PATH"Then run
just gui(ornpm run tauri dev) in the same shell. You can add that line to your shell profile if you use the GUI often. -
Otherwise, set
PKG_CONFIG_PATHto the directory that contains the.pcfile, or install the matching-devel/-devpackage for that library.
Linux: dark mode and window theme
On Linux, Tauri does not yet reliably propagate the system theme to the WebView or native window (see tauri#9427). The app works around this by reading the XDG Settings portal (org.freedesktop.appearance.color-scheme) and applying dark/light to the in-app UI. So the content of the window should follow your system dark/light preference. The window border and title bar are drawn by the desktop and may stay light until Tauri/tao adds full Linux theme support; there is no theme option in tauri.conf.json for Linux (it is only implemented on Windows and macOS).
Development
Bootstrap (first-time setup)
Before running the GUI or building the app, set up the repo once:
-
Install dependencies (Node and Tauri CLI):
npm installIf you see
tauri: command not foundwhen runningjust gui, the Tauri CLI is missing — runnpm installfrom the project root. -
Create the frontend build output so Tauri can load the UI. The config expects
dist/at the project root. Either build the frontend once:npm run buildor create an empty directory (the app will start but the window will have no UI until you run
npm run build):mkdir -p dist -
On Linux, install system libraries for the GUI and, if you use Linuxbrew, set
PKG_CONFIG_PATHas described there.
Then you can run just gui or the commands below.
Daily workflow
- GUI:
just guiornpm run tauri dev(Rust is built first so the window opens when the backend is ready). - CLI:
just cli generate --output-dir ./out --text "Hello"orjust cli generate --output-dir ./out --file prompts.txt. - Tests:
just testorcargo test --manifest-path src-tauri/Cargo.toml.
Optional: use the Tauri Development launch config in VS Code (Run and Debug) to run the GUI.
Common issues
-
just guifails with "webkit2gtk-4.1", "libsoup-3.0", or "javascriptcoregtk-4.1" not found
You need the Linux system libraries for the GUI. See Linux: system libraries for the GUI. On Fedora you can runjust gui-depsto print the install command. -
frontendDistconfiguration is set to"../dist"but this path doesn't exist
Tauri requires thedist/directory (built frontend). Runnpm run buildonce to create it, ormkdir -p distfor an empty placeholder. -
tauri: command not found
The Tauri CLI is provided by npm. Runnpm installin the project root sonode_modules/.binincludes it; then usejust guiornpm run tauri dev(do not runtauridirectly unless it’s on your PATH). -
Blank window on first open (dev)
The window can open before the Vite dev server is ready. Reload the window (e.g. Ctrl+R / Cmd+R) or start the dev server first (npm run dev), then runjust guiin another terminal. -
Title bar
The native title bar is drawn by the OS and does not follow the app’s CSS or dark mode. To have the title bar match the app, you’d need to setdecorations: falseand implement a custom HTML/CSS title bar with a drag region (and optionally window controls via the Tauri window API).
Build
- Windows: On Windows with WiX and NSIS installed,
npm run tauri build -- --bundles msi,nsisproduces an MSI insrc-tauri/target/release/bundle/msi/and an NSIS.exeinsrc-tauri/target/release/bundle/nsis/. The NSIS installer prompts for per-user or per-machine install (seebundle.windows.nsis.installMode: "both"intauri.conf.json). - macOS (.app): On macOS,
npm run tauri buildproduces the app bundle (e.g. insrc-tauri/target/release/bundle/macos/). - Linux:
npm run tauri buildproduces .deb and AppImage. In environments without FUSE (e.g. Docker, CI), setAPPIMAGE_EXTRACT_AND_RUN=1so the linuxdeploy AppImage can run. If you see “Squashfs image uses (null) compression” when launching via AppImageLauncher, run./scripts/repack-appimage-gzip.sh path/to/foo.AppImageor run the AppImage directly. Release builds are repacked with gzip so AppImageLauncher can read them. If you get "Could not create default EGL display: EGL_BAD_PARAMETER" and a blank window (e.g. on Fedora with some GPUs): run withWEBKIT_SKIA_ENABLE_CPU_RENDERING=1 ./Announcemint_*.AppImageto force CPU rendering. Release builds use a repack step that injects this into the AppImage’s AppRun (script or binary), so newer builds should avoid the crash; to try GPU again useWEBKIT_SKIA_ENABLE_CPU_RENDERING=0before launching.
Rebranding
Edit brand.json at the project root:
publisher– Used in the config directory path (e.g.~/.config/<publisher>/<appName>/).appName– Display name (window title, headers, About). Also used in the config path.docsUrl– URL opened by the Help button; also used for the opener permission in capabilities.githubRepo– URL for the GitHub link on the About screen.shortDescription/longDescription– Bundle metadata (e.g. for installers).
Then run npm run sync-brand to update src-tauri/tauri.conf.json (product name, window title, identifier, CLI description) and src-tauri/capabilities/default.json (docs URL allow list). The build and dev commands run sync-brand automatically. Rebuild the app so the Rust backend picks up the new publisher/app name for the config directory.
Optionally update package.json name and the CLI binary name in src-tauri/src/cli.rs if you want the npm package and CLI command to match your brand.
License
GPL-3.0. See LICENSE.