macOS menu bar utility that rewrites each mouse-wheel notch to a fixed line step. Trackpad input, momentum, and gesture phases pass through untouched.
- Fixed step per notch: Slow (2 lines) or Medium (3 lines)
- Option-key precision drops to 1 line per notch
- Terminal heuristic emits 1 line per notch in terminal apps, configured step when Option is held
- Natural scroll-direction toggle
- Mouse button 4 maps to the macOS Look Up gesture
- Optional sleep-prevention assertion while enabled; display sleep, lid close, and manual sleep still fire
- Launch at login via
SMAppService - Pass-through for continuous, phased, diagonal, and zero-delta events
Settings live in a single window opened from the menu bar icon.
- macOS 15+
- Apple silicon (arm64)
- Accessibility permission
Download the signed arm64 archive from Releases and drop Probo.app into /Applications.
First launch routes through the menu bar icon. Enabling Probo or selecting Request Access opens System Settings > Privacy & Security > Accessibility; the event tap installs as soon as macOS reports the grant.
Requires Xcode command-line tools. Local builds codesign with a self-minted identity created on first run.
scripts/dev/run.shWrites build/Probo.app and relaunches it. Set PROBO_CODESIGN_IDENTITY=- for ad-hoc signing.
AppKit owns the menu bar item, status menu, settings window, and settings controls over a native Swift rewrite core. The event-tap callback reads raw CGEvent fields, applies the terminal heuristic, asks the core for a rewrite decision, and synthesizes a replacement scroll event when needed. Hot path is allocation-free.
| Layer | Path | Role |
|---|---|---|
| App | probo/Sources/App |
Lifecycle, controller wiring |
| Core | probo/Sources/Core |
Pure rewrite hot path |
| Events | probo/Sources/Events |
Event tap, scroll synthesis |
| Configuration | probo/Sources/Configuration |
Settings model, persistence |
| System | probo/Sources/System |
Accessibility, frontmost app, sleep, login |
| UI | probo/Sources/UI |
Status menu and settings controls |
| Tools | probo/Tools |
Probes, diagnostics |
No SwiftPM manifest, no Xcode project. Shell scripts drive every workflow.
| Script | Purpose |
|---|---|
swift-format format -i -r probo/Sources probo/Tests |
Format sources and tests |
scripts/test.sh |
Build and run BDD-style Swift tests |
scripts/build.sh |
Build and codesign the bundle (shared with CI) |
scripts/dev/run.sh |
Build and relaunch Probo.app |
scripts/dev/lsp.sh |
Generate compile_commands.json for SourceKit-LSP |
scripts/dev/setup-codesign.sh |
Create local signing identity |
scripts/profiling/hot-path.sh |
Hot-path micro profiles or xctrace recordings |
scripts/ci/mint-identity.sh |
Emit p12 and passphrase for CI signing secrets |
Re-run scripts/dev/lsp.sh after source-layout or compiler-flag changes so the IDE matches the shell build.
CI runs on every push and pull request. CD publishes a rolling latest GitHub release with a signed arm64 archive after CI passes on main.
Release signing reads PROBO_RELEASE_P12_BASE64 and PROBO_RELEASE_P12_PASSWORD. Missing either falls back to an ad-hoc signature with a warning.