initial commit: native macOS app for transcriptor-ai

SwiftUI app, the one-click way to use the local transcription pipeline —
installs and runs with no separate manual steps. The Xcode build phase
(scripts/embed-binaries.sh) builds audiotee (git submodule, pinned to a
commit on our own Gitea fork) and transcriptor-ai + qwen_asr (sibling
checkout, which itself vendors qwen-asr as a submodule), then embeds all
three binaries in the app bundle. The AI model is the one thing still
fetched at runtime, via ModelManager.swift, since it's multi-GB and
doesn't belong baked into a build.

Also implements: model download with real progress UI, capture source
selection (system/mic/both), a Settings window for the transcript save
location and a glossary file (biases ASR toward proper nouns/product
names via qwen_asr's --prompt), and a live chat-bubble transcript view.

See CLAUDE.md for the full architecture, the reasoning behind each
decision, and a fairly long list of real bugs found via actual testing
(not just code review) — TCC permission escalation through a subprocess
tree, SwiftUI Form/Grid layout quirks, @State vs @AppStorage persistence,
a prompt-leakage bug in the glossary feature, and more.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sttlab-tech
2026-08-09 13:26:29 +02:00
commit 8bd1a6caf8
23 changed files with 2288 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
#!/bin/bash
# Xcode "Run Script" build phase: builds audiotee, transcriptor-ai, and
# qwen_asr from the sibling repos and embeds them in this app's bundle —
# the "one-click install" requirement (see CLAUDE.md, "Goal"). Only the AI
# model is left to fetch at runtime; everything else is baked in here.
#
# Expects Xcode's build environment variables (SRCROOT, BUILT_PRODUCTS_DIR,
# UNLOCALIZED_RESOURCES_FOLDER_PATH). Run manually for debugging via:
# SRCROOT=$(pwd) BUILT_PRODUCTS_DIR=/tmp/embed-test \
# UNLOCALIZED_RESOURCES_FOLDER_PATH=transcriptor.app/Contents/Resources \
# scripts/embed-binaries.sh
set -euo pipefail
# Xcode Run Script phases don't inherit a normal interactive-shell PATH —
# Homebrew's go/etc. aren't found without this (bit us during manual
# testing throughout this session too).
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
SRCROOT="${SRCROOT:?SRCROOT must be set (run via Xcode, or set it manually — see header comment)}"
REPO_ROOT="$(cd "$SRCROOT" && pwd)"
AUDIOTEE_REPO="$(cd "$REPO_ROOT/../audiotee" && pwd)"
TRANSCRIPTOR_AI_REPO="$(cd "$REPO_ROOT/../transcriptor-ai" && pwd)"
echo "Building audiotee..."
"$AUDIOTEE_REPO/scripts/build-signed.sh"
echo "Building transcriptor-ai + qwen_asr..."
"$TRANSCRIPTOR_AI_REPO/scripts/build-dist.sh"
RESOURCES_DIR="${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
mkdir -p "$RESOURCES_DIR"
cp "$HOME/bin/audiotee" "$RESOURCES_DIR/audiotee"
cp "$TRANSCRIPTOR_AI_REPO/dist/transcriptor-ai" "$RESOURCES_DIR/transcriptor-ai"
cp "$TRANSCRIPTOR_AI_REPO/dist/qwen_asr" "$RESOURCES_DIR/qwen_asr"
chmod +x "$RESOURCES_DIR/audiotee" "$RESOURCES_DIR/transcriptor-ai" "$RESOURCES_DIR/qwen_asr"
echo "Embedded binaries in $RESOURCES_DIR:"
ls -la "$RESOURCES_DIR/audiotee" "$RESOURCES_DIR/transcriptor-ai" "$RESOURCES_DIR/qwen_asr"