Conversation
…pending new content When SFSpeechRecognizer reformulates text by prepending new content before already-consumed text, the previous code showed the full reformulated text (including already-finalized content) as liveText. - Detect when currentText ends with lastConsumedPartial (suffix match) - Show only the new prefix portion as liveText and update lastConsumedPartial - Add stripLeadingPunctuation() helper to remove leading commas/whitespace from liveText and all subtitle entry commits
Default values updated to match preferred configuration: - Font size: 24pt -> 20pt - Background opacity: 70% -> 50% - Subtitle expiry: 10s -> 20s - Speech pause: 2.0s -> 3.0s - Display mode: combined -> split - Overlay lock: true -> false (both windows) FontSettingsView live preview now reflects the active display mode: - Split mode: two side-by-side boxes (Recognition | Translation) - Combined mode: single box with original and translated text
Temporarily lower the session window level to .normal before showing the save panel, then restore the original level after it closes.
- SessionHistoryView: handle export write errors with do/catch, AppLogger, and NSAlert instead of silently ignoring via try? - AppState: remove lastConsumedPartial override in suffix-strip branch to prevent newPart (live unconsumed text) from being silently dropped - AppState: use .whitespacesAndNewlines in stripLeadingPunctuation to also remove leading newlines - FontSettingsView: gate split-mode preview panes on showOriginalText and showTranslation toggles for accurate visibility reflection
- Replace "Recognition" with "Transcription" throughout UI - Move on-device recognition toggle from Debug to Languages tab - Add version display in About tab from Bundle info - Update Display Mode descriptions to use Transcription/Translation - Simplify overlay window section titles for split mode
- Add SFSpeechRecognizerDelegate for availability monitoring - Periodically recreate recognizer to prevent resource exhaustion - Use taskGeneration counter to filter stale callbacks - Add retry mechanism (3 attempts, 2s delay) for restart failures - Replace DispatchQueue.main.asyncAfter with Task-based delay
- Fix thread safety in SystemAudioCapture with lock-protected properties - Reconfigure translation source on auto-detected language change - Invalidate translation session on capture stop - Add HTTP status check in fallback Google Translate API
- Guard auto-scroll with isAtBottom check in all overlay views - Only auto-scroll when user is at bottom or overlay is locked
# Conflicts: # OST/Sources/App/AppState.swift # OST/Sources/App/OSTApp.swift # OST/Sources/Audio/SystemAudioCapture.swift # OST/Sources/Settings/UserSettings.swift # OST/Sources/Speech/SpeechRecognizer.swift # OST/Sources/Translation/TranslationService.swift # OST/Sources/UI/FontSettingsView.swift # OST/Sources/UI/LanguagePickerView.swift # OST/Sources/UI/RecognitionOverlayView.swift # OST/Sources/UI/SessionHistoryView.swift # OST/Sources/UI/SubtitleView.swift # OST/Sources/UI/TranslationOverlayView.swift
There was a problem hiding this comment.
Pull request overview
This PR prepares OST for release readiness by hardening packaging/build validation, documenting a manual QA flow, and making numerous runtime/UX fixes around capture startup, permissions, speech restarts, translation session lifecycle, online fallback policy, settings changes, overlay windows, and session history persistence. Version is rolled back from 1.0.0 to 0.0.4 to reflect that public release still requires human-owned Developer ID notarization.
Changes:
- Hardened build (
build.sh) and CI to enforce ad-hoc signing, entitlement parity, Info.plist keys, ZIP validation, and strict-concurrency warnings-as-errors. - Significant refactor of runtime: TranslationService generations + fallback policy, opt-in online fallback, capture lifecycle generations in
OSTApp/AppState, SessionRecorder per-entry IDs and atomic-save, SystemAudioCapture sendable buffer wrapper and permission preflight, Settings safeXxx clamping, overlay window clamping/locking. - Documentation updates: README (en/ko/zh/ja), CLAUDE.md, new
AGENTS.md, newdocs/manual-qa.md, PR/issue templates, CI release job.
Reviewed changes
Copilot reviewed 36 out of 38 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| README.md / README.ko.md / README.zh.md / README.ja.md | Update disclaimer, permissions, defaults, troubleshooting, build/test docs |
| project.yml | Swift version "5", version 0.0.4 |
| OST/Resources/Info.plist | Add NSAudioCaptureUsageDescription, version 0.0.4 |
| OST/Sources/UI/*.swift | safeXxx settings clamping; translation status surface; lock defaults; recovery actions |
| OST/Sources/UI/SessionHistoryView.swift | Confirm dialog for clear, displayedSession lookup |
| OST/Sources/UI/OverlayWindow.swift | Move resetFrame logic to WindowManager; clampToScreen with finite checks |
| OST/Sources/UI/LogViewerView.swift | Smart auto-scroll |
| OST/Sources/UI/LanguagePickerView.swift | Availability state with installed/supported/unsupported; online fallback toggle |
| OST/Sources/Translation/TranslationConfig.swift | Availability state enum; same-language pair detection |
| OST/Sources/Translation/TranslationService.swift | Generations, error type, online fallback gating, waitForSessionReady |
| OST/Sources/Speech/SpeechRecognizer.swift | Cleanup on start failure; preserve finalized text; safer restart retries |
| OST/Sources/Settings/UserSettings.swift | Sanitization + clamped accessors; default overlays locked |
| OST/Sources/Audio/SystemAudioCapture.swift | AudioSampleBuffer wrapper, CG preflight, stream identity checks |
| OST/Sources/App/WindowManager.swift | Display-mode tracking; clamped reset; settings callbacks; isReleasedWhenClosed=false |
| OST/Sources/App/SessionRecorder.swift | Entry IDs, update/clear translations, discard empty session, robust load/save |
| OST/Sources/App/OSTApp.swift | Capture lifecycle generations, runtime settings/language change handlers, recovery actions |
| OST/Sources/App/AppState.swift | startingCapture state, robust generation guards, refresh translations, common-mode timers |
| OST/Sources/Accessibility/AccessibilityManager.swift | Mark @MainActor |
| docs/manual-qa.md | New manual QA checklist |
| build.sh, CLAUDE.md, AGENTS.md | Strict concurrency, framework link checks, plist asserts, entitlements parity |
| .github/workflows/build.yml | PR/main triggers, ZIP validation, separate release job |
| .github/pull_request_template.md, ISSUE_TEMPLATE/* | New PR template, expanded bug/feature templates |
| .gitignore | Ignore test/release artifacts |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification
./test.sh./build.sh --typecheck./build.shgit diff --checkdocs/manual-qa.mdd3af25ee780f69ee843cb306b9437a4b3abe4e380d956f2819c7ab2a78a7b663Manual QA Still Required