Oak is a lightweight macOS focus companion designed for deep work with notch-first UI and ambient sounds.
- macOS 13+ (Apple Silicon recommended)
- XcodeGen (
brew install xcodegen) - for building from source - SwiftLint (optional, for code linting:
brew install swiftlint) - SwiftFormat (optional, for code formatting:
brew install swiftformat)
Important
We don't have an Apple Developer account yet. The application will show a popup on first launch that the app is from an unidentified developer.
- Click OK to close the popup.
- Open System Settings > Privacy & Security.
- Scroll down and click Open Anyway next to the warning about the app.
- Confirm your choice if prompted.
You only need to do this once.
In today's world of constant distractions, deep work has become increasingly rare and valuable. Oak was created to help you reclaim your focus and establish productive work sessions without cluttering your screen. By leveraging the MacBook's notch area, Oak provides a subtle, always-visible timer that keeps you accountable without being intrusive.
- π― Notch-first UI: Elegant focus companion that lives in your MacBook's notch
- β±οΈ Pomodoro presets: Default
25/5and50/10sessions (fully configurable) - π Smart breaks: Automatic 15/20 min long breaks after 4 focus rounds
βΆοΈ Session controls: Start, pause, and resume your focus sessions- π΅ Ambient sounds: Rain, forest, cafe, brown noise, and lo-fi to help you concentrate
- π Local tracking: Track daily focus minutes, completed sessions, and 7-day streaks
- π Auto-update: Seamless updates via Sparkle framework
# Add the tap
brew tap jellydn/oak https://github.com/jellydn/oak
# Install Oak
brew install --cask oak# Clone the repository
git clone https://github.com/jellydn/oak.git
cd oak
# Generate Xcode project
cd Oak && xcodegen generate
# Build and run
open Oak.xcodeproj# Show available commands
just
# Build the project
just build
# Build release version
just build-release
# Run all tests
just test
# Run tests with verbose output
just test-verbose
# Run a specific test class
just test-class FocusSessionViewModelTests
# Run a specific test method
just test-method FocusSessionViewModelTests testStartSession
# Check for compilation errors
just check
# Clean build artifacts
just clean
# Open in Xcode
just open
# Validate bundled ambient sound files
just check-soundsOak expects bundled ambient files under Oak/Oak/Resources/Sounds with these base names:
ambient_rainambient_forestambient_cafeambient_brown_noiseambient_lofi
Supported extensions: .m4a (preferred), .wav, .mp3.
The ambient sounds included in Oak are sourced from Pixabay under the Pixabay Content License:
- Rain Sound: Real Rain Sound by feedthestraycats
- Forest Sound: Ambient Spring Forest by soundreality
- Cafe Sound: Cafe Noise by freesound_community
- Brown Noise: Brown Noise by digitalspa
- Lo-fi Sound: Lofi Guitar by freesound_community
We are grateful to these creators for making their work available for projects like Oak.
Oak uses the Sparkle framework to provide automatic updates. Updates are checked automatically on launch and can be configured in Settings:
- Automatic update checks: Enable/disable automatic update checking (enabled by default)
- Automatic downloads: Enable/disable automatic download of updates (disabled by default for user control)
- Manual check: Check for updates on demand via Settings
The appcast feed is served from appcast.xml in the repository root and is automatically updated when new releases are published.
Oak is configured with Sparkle EdDSA signing (SUPublicEDKey) and appcast entries include sparkle:edSignature.
# Lint Swift code
just lint
# Auto-fix linting issues
just lint-fix
# Format Swift code
just format
# Check if code is formatted correctly
just format-check
# Run both lint and format checks
just check-style- CI runs on GitHub Actions (
.github/workflows/ci.yml) forpushtomainand all PRs. - Auto-release (
.github/workflows/auto-release.yml) automatically creates a new release when changes are merged tomain:- Automatically increments the patch version (e.g.,
v0.1.0βv0.1.1) - Creates a Git tag
- Builds and publishes artifacts to GitHub Releases
- Automatically increments the patch version (e.g.,
- Manual release workflow (
.github/workflows/release.yml) builds and publishes unsigned artifacts on:- tag push:
v*(example:v0.1.0) - manual dispatch with a
versioninput (example:v0.1.0)
- tag push:
If you need to create a specific version manually:
git tag v0.1.0
git push origin v0.1.0The release uploads:
Oak-<version>.dmgOak-<version>.zip
- Artifacts are built unsigned (
CODE_SIGNING_ALLOWED=NO). - The app is not notarized.
- Users will need to bypass Gatekeeper on first launch (Right-click app -> Open).
Oak/
βββ Oak/
β βββ Models/ # Data models, enums, protocols
β βββ Views/ # SwiftUI Views
β βββ ViewModels/ # ObservableObject classes
β βββ Services/ # Business logic, audio, persistence
β βββ Resources/ # Assets, sounds, config files
β βββ OakApp.swift # App entry point
βββ Oak.xcodeproj/ # Generated by XcodeGen
βββ project.yml # XcodeGen config (project definition)
βββ Tests/ # Unit tests
Note: This project uses XcodeGen for project management. The Xcode project is generated from project.yml. Do not use Swift Package Manager (swift build or swift test) for this project.
- PRD - Product Requirements Document
- Architecture Decisions - ADRs for key technical decisions
- Agent Guidelines - Development guidelines for contributors
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
This project is licensed under the MIT License - see the LICENSE file for details.
π€ Dung Huynh
- Website: https://productsway.com
- Twitter: @jellydn
- GitHub: @jellydn
Give a βοΈ if this project helped you!
Thanks goes to these wonderful people:
This project follows the all-contributors specification. Contributions of any kind welcome!
