AGENTS.md
AGENTS.md
not.boring.notch is a fork of Boring Notch (GPL-3.0). It is a macOS notch app (SwiftUI + AppKit) that is compact-only and bridges to Raycast. Read VISION.md for what we're building and docs/UPSTREAM-SYNC.md for how we stay in sync with upstream.
Git
- Remotes:
origin= notkainoa/not.boring.notch,upstream= TheBoredTeam/boring.notch. - Our
mainis the product branch. It started as a one-time snapshot of upstreamdev(v2.8-rc.2 plus fixes, merged with upstreammain's trailing CI commits). Upstream's ownmainis stale, so it is not the base for anything. - We have deliberately diverged from upstream and do not merge it.
upstreamstays as a fetch-only remote so we can cherry-pick security and macOS-compatibility fixes and look at their PRs. Seedocs/UPSTREAM-SYNC.md. - Commits are authored as Kainoa Newton k@kainoa.me. Flag it if
git config user.emaildiffers. - Don't push or open PRs unless asked.
origin/mainis still upstream's stalemain, and ourmainis a fast-forward of it. - Never rewrite history that has been pushed.
Project layout
boringNotch/is the app. Key places:ContentView.swift: the notch root view, with open/closed layout and compact-mode branching.components/Notch/:CompactHomeView,NotchHomeView, the SkyLight window, live-activity stack and power notice.components/LiveActivities/,components/OSD/: the temporary alerts and HUD replacement.components/Calendar/,Webcam/,Shelf/,Music/,Tabs/: features.managers/NotchWindowManager.swift: per-display windows and lock-screen (SkyLight) toggling.models/Constants.swift: everyDefaultskey. Add settings here.sizing/matters.swift: notch size computation. It has non-notch handling.
BoringNotchXPCHelper/: XPC helper for sandbox-restricted work such as media keys and HUD interception.mediaremote-adapter/: now-playing source on macOS 15.4+.- Settings UI lives in
components/Settings/Views/.
Working agreements
- We're not tracking upstream, so refactor and delete freely. Remove code for features we cut (non-compact layout, tabs) instead of leaving it dormant.
- New user-facing strings go in
Localizable.xcstrings. - Upstream's release, nightly, Crowdin, Pages and fork-PR-policy workflows were deleted (they depended on upstream's secrets and infrastructure). What remains in
.github/is CI (build and test), CodeQL, SwiftLint and Dependabot, all targetingmain. Auto-update (Sparkle) is disabled. The plan for releasing is inVISION.mditem 9. - Translations are no longer synced from Crowdin. Edit
Localizable.xcstringsdirectly. - New settings are
Defaultskeys inConstants.swiftwith a settings-UI entry. - Keep the notch cheap at rest (CPU, memory, no polling). Upstream has fixed several hot-path regressions.
- The app must work on notched and non-notched displays (MacBook Air, Mac mini, external monitors). Design for both. See "Building and testing" for how testing works.
- Deployment target is macOS 14.0, but check the target before using newer APIs.
- Mark anything that depends on Apple private API (SkyLight, MediaRemote) clearly. It is the likeliest thing to break on a new macOS release.
Building and testing
Use scripts/dev.sh from any checkout or worktree. If your worktree predates it, get it with git cherry-pick 41926b5 (or git merge main).
| 1 | scripts/dev.sh # build and run this checkout |
| 2 | scripts/dev.sh build # build only |
| 3 | scripts/dev.sh kill # stop this checkout's copy |
- It builds ad-hoc signed into
.build/devin your own checkout, which is gitignored, so worktrees don't share build output. runstarts the binary directly (logs go to the terminal, Ctrl-C quits).- The dev build has the same bundle ID and XPC service name as the installed Boring Notch.
runrefuses to start while/Applications/Boring Notch.appis running, so the user has to quit it first (the notch context menu has Quit). Only one build can run at a time. - Ad-hoc signing changes identity on each rebuild, so macOS re-asks for Accessibility and other permissions after a rebuild. Expect that and tell the user when a feature depends on one.
- The XPC service name in
XPCHelperClient.swiftis hard-coded to the helper's bundle ID. Don't change bundle IDs without updating it.
Agent rules for testing
- Agents never launch the app. Several agents share this Mac and the user may be using it. Don't run
scripts/dev.sh run,openthe built app, or drive the desktop. Verify withscripts/dev.sh build(or thexcodebuildcommand in that script), unit tests, and code reasoning only. scripts/dev.sh buildis the compile check. Report its result honestly, including environment failures.- Be explicit about what is unverified at runtime. Lock screen, Bluetooth hardware, HUD interception, notch animation feel and non-notch displays can't be confirmed by building.
When you finish, hand the user a test plan
End your final report with a "How to test" section the user can follow, containing:
- The exact commands, with the absolute worktree path, for example
cd ~/.t3/worktrees/not.boring.notch/<worktree> && scripts/dev.sh. - A reminder to quit the installed Boring Notch first if it's running.
- Which permissions the feature needs (Accessibility, Bluetooth, Calendar, Camera, and so on), and that they may need re-granting after a rebuild.
- A short checklist of what to try and what a correct result looks like, including edge cases (non-notch display, external monitor, lock screen, no music playing, etc., as relevant).
- Known gaps: what you couldn't verify and where you'd expect problems.
The user's test devices are a non-notch MacBook Air M1 and, later, an external monitor.
Licensing
Everything here is GPL-3.0. Code copied from other projects (MewNotch and DynamicNotch are GPL-3.0 reference implementations) needs its attribution kept and has to be compatible with GPL-3.0. Add new third-party notices to THIRD_PARTY_LICENSES/.