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
@@ -0,0 +1,35 @@
//
// transcriptorUITestsLaunchTests.swift
// transcriptorUITests
//
// Created by Stéphane Tailland on 08/08/2026.
//
import XCTest
final class transcriptorUITestsLaunchTests: XCTestCase {
override class var runsForEachTargetApplicationUIConfiguration: Bool {
true
}
override func setUpWithError() throws {
continueAfterFailure = false
}
@MainActor
func testLaunch() throws {
let app = XCUIApplication()
app.launch()
// Insert steps here to perform after app launch but before taking a screenshot,
// such as logging into a test account or navigating somewhere in the app
// XCUIAutomation Documentation
// https://developer.apple.com/documentation/xcuiautomation
let attachment = XCTAttachment(screenshot: app.screenshot())
attachment.name = "Launch Screen"
attachment.lifetime = .keepAlways
add(attachment)
}
}