WhisperServer/: Swift sources (e.g.,WhisperServerApp.swift,VaporServer.swift,WhisperTranscriptionService.swift,ModelManager.swift,Assets.xcassets/).WhisperServer.xcodeproj/: Xcode project and build settings.test_api.sh: Curl-based API smoke/streaming tests.jfk.wav: Sample audio used by tests.Resources/,BuildPhases/: Supporting assets and scripts.
- Build (CLI):
xcodebuild build -project WhisperServer.xcodeproj -scheme WhisperServer. - Run (GUI): Open in Xcode and press Run (⌘R). The app starts a server on
http://localhost:12017. - API test suite:
./test_api.sh(app must be running). Example:curl -X POST http://localhost:12017/v1/audio/transcriptions -F file=@jfk.wav -F response_format=json. - App icon generation:
./GenerateAppIcon.sh(usesicon.png).
- Swift 5, 4-space indentation, keep lines readable (~120 cols).
- Types: PascalCase; methods/properties: lowerCamelCase; one primary type per file named after the type.
- Prefer
guardfor early exits; avoid force-unwraps; keep async work off the main thread. - Do not commit model binaries:
.gitignoreexcludes*.bin,*.mlmodelc. - Comments and strings in code must be written in English only.
- Favor enums and strong types over string literals for modes and formats (e.g., response formats).
- Centralize shared constants (e.g., notification names) in a single place.
- Limit logging to actionable or error information; avoid verbose debug prints in production paths.
- Primary: run the app, then
./test_api.shto validate JSON/text/SRT/VTT and streaming (SSE/chunked). - Manual checks: use
curlwith-F file=@jfk.wavandresponse_format(json|text|srt|vtt|verbose_json). - If adding Xcode tests, follow
test[Component][Behavior]()naming and keep tests independent of network state.
- Commit style (per history): concise, imperative present tense, mention affected components (e.g., “Refactor WhisperTranscriptionService…”), include the “why” when useful.
- PRs: clear description, scope of change, testing steps (
xcodebuild build,./test_api.shresults), linked issues, and screenshots if UI/menu-bar behavior changes.
- Default port is
12017. The server binds tolocalhostby default; users can opt in to0.0.0.0via the "Expose on Local Network" menu bar toggle. - LAN requests may optionally require a bearer token via the "Require API Key" toggle. Tokens live in
APIKeyStore(Keychain-backed, service = bundle id, account =whisper-api-key).APIKeyAuthMiddlewareenforces the check at the Vapor layer; loopback clients (127.0.0.1 / ::1) always bypass to keep local tooling working. - User preferences (launch-at-login, LAN exposure, require-API-key) live in
SettingsStoreand are persisted viaUserDefaults. Launch-at-login usesSMAppService.mainApp(no helper target). - Large Whisper models live outside the repo; configure via the app UI; never commit model files.
- Target platform is modern macOS only. Cross‑platform fallbacks and conditional compilation are not required.
- Vapor route handlers should use async/await.
- Prefer streaming SSE for incremental results; always terminate SSE with an explicit
endevent. - Ensure temporary files are cleaned up after each request (success or failure).
- When bridging Swift strings to C APIs, allocate stable C strings (e.g., via
strdup) and free them after use. - Always validate and unwrap external resources (contexts, files, model paths) before use; return early on failure.
- Avoid blocking calls on UI threads; dispatch UI changes to the main thread.