Skip to content

Commit 83273fc

Browse files
committed
feat: initial release v0.0.1
Real-time speech recognition and translation overlay for macOS. Captures system audio via ScreenCaptureKit, transcribes with SFSpeechRecognizer, translates using Apple Translation framework, and displays subtitles in a floating overlay window.
0 parents  commit 83273fc

34 files changed

Lines changed: 2657 additions & 0 deletions

.github/workflows/build.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Build and Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
9+
jobs:
10+
build:
11+
runs-on: macos-15
12+
permissions:
13+
contents: write
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
19+
- name: Build
20+
run: ./build.sh
21+
22+
- name: Create ZIP
23+
run: |
24+
cd build
25+
zip -r ../OST.zip OST.app
26+
27+
- name: Upload artifact
28+
uses: actions/upload-artifact@v4
29+
with:
30+
name: OST.app
31+
path: OST.zip
32+
33+
- name: Create Release
34+
if: startsWith(github.ref, 'refs/tags/')
35+
uses: softprops/action-gh-release@v2
36+
with:
37+
files: OST.zip
38+
generate_release_notes: true

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Build output
2+
build/
3+
4+
# Xcode
5+
OST.xcodeproj/
6+
*.xcworkspace/
7+
xcuserdata/
8+
DerivedData/
9+
10+
# macOS
11+
.DS_Store
12+
13+
# Reference project (not part of OST)
14+
ref-project/
15+
16+
# OMC state
17+
.omc/
18+
19+
# Claude Code
20+
CLAUDE.md

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 9bow
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

OST/Resources/Info.plist

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleName</key>
6+
<string>OST</string>
7+
<key>CFBundleDisplayName</key>
8+
<string>On-Screen Translator</string>
9+
<key>CFBundleIdentifier</key>
10+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11+
<key>CFBundleVersion</key>
12+
<string>1</string>
13+
<key>CFBundleShortVersionString</key>
14+
<string>1.0.0</string>
15+
<key>CFBundlePackageType</key>
16+
<string>APPL</string>
17+
<key>CFBundleExecutable</key>
18+
<string>$(EXECUTABLE_NAME)</string>
19+
<key>LSMinimumSystemVersion</key>
20+
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
21+
<key>LSUIElement</key>
22+
<true/>
23+
<key>NSSpeechRecognitionUsageDescription</key>
24+
<string>OST needs speech recognition access to transcribe system audio in real-time.</string>
25+
<key>NSSystemAudioRecordingUsageDescription</key>
26+
<string>OST needs system audio recording access to capture audio for transcription and translation.</string>
27+
</dict>
28+
</plist>

OST/Resources/OST.entitlements

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict/>
5+
</plist>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import AppKit
2+
import SwiftUI
3+
4+
enum AccessibilityManager {
5+
6+
// MARK: - VoiceOver Announcements
7+
8+
/// Posts a VoiceOver announcement with the given message.
9+
static func announce(_ message: String) {
10+
let userInfo: [NSAccessibility.NotificationUserInfoKey: Any] = [
11+
.announcement: message,
12+
.priority: NSAccessibilityPriorityLevel.medium.rawValue
13+
]
14+
NSAccessibility.post(
15+
element: NSApp as Any,
16+
notification: .announcementRequested,
17+
userInfo: userInfo
18+
)
19+
}
20+
21+
/// Posts a layout-changed notification to inform VoiceOver of UI updates.
22+
static func postLayoutChanged(for element: AnyObject = NSApp) {
23+
NSAccessibility.post(element: element, notification: .layoutChanged, userInfo: nil)
24+
}
25+
26+
// MARK: - High Contrast Detection
27+
28+
/// Returns true when the system high-contrast accessibility setting is enabled.
29+
static var isHighContrastEnabled: Bool {
30+
NSWorkspace.shared.accessibilityDisplayShouldIncreaseContrast
31+
}
32+
33+
/// Returns the recommended minimum font size respecting accessibility preferences.
34+
static func effectiveFontSize(base: CGFloat) -> CGFloat {
35+
isHighContrastEnabled ? max(base, 18) : base
36+
}
37+
38+
// MARK: - Focus Management
39+
40+
/// Moves VoiceOver focus to the given NSView element.
41+
static func moveFocus(to element: NSView) {
42+
NSAccessibility.post(element: element, notification: .focusedUIElementChanged, userInfo: nil)
43+
}
44+
}
45+
46+
// MARK: - SwiftUI View Modifier Helpers
47+
48+
extension View {
49+
/// Adds a combined accessibility element with label and hint.
50+
func accessibilityDescribe(label: String, hint: String? = nil) -> some View {
51+
self
52+
.accessibilityLabel(label)
53+
.accessibilityHint(hint ?? "")
54+
.accessibilityElement(children: .combine)
55+
}
56+
}

0 commit comments

Comments
 (0)