A macOS GUI tool written in Go for managing background tasks, login items, launch agents, and daemons — everything shown in System Settings → General → Login Items & Extensions.
- Lists all items from the BTM (Background Task Manager) database via
sfltool dumpbtm - Shows full details: name, developer, team ID, identifier, executable path, URL, disposition, bundle IDs, generation, UUID
- Filter by type (Login Item, Launch Agent, Daemon, App, Background App Refresh, Developer Tool, QuickLook, Spotlight) and search by name/identifier/developer
- Enable/disable items (uses
launchctlfor agents/daemons,pluginkitfor login items) - Remove items — deletes the plist file from disk and unloads the service
- Inline plist viewer — when an item URL points to a
.plistfile, displays its content in the detail panel - Visual enabled/disabled status indicator per item in the list
- Keyboard navigation in the item list
- Dark theme UI
- macOS 13 (Ventura) or later
- Go 1.22+
- Xcode Command Line Tools (for Fyne's OpenGL dependencies)
xcode-select --install# 1. Clone / download the project
cd btmgr
# 2. Build
make build
# 3. Run (sudo is needed for sfltool dumpbtm)
make run
# or
sudo ./build/btmgrmake bundle
open build/BTManager.appNote: The app needs
sudo(or appropriate entitlements) to read the BTM database viasfltool dumpbtm. Enabling/disabling user-level agents and login items runs as the current user without sudo. Operations on system daemons and file deletion outside~/prompt for administrator credentials via a native macOS dialog.
| Action | How |
|---|---|
| View all items | Launch the app — list loads automatically |
| Filter by type | Use the Type dropdown |
| Search | Type in the search box (matches name, identifier, developer) |
| View details | Click any item in the list |
| Enable/Disable item | Select item → click "Enable" or "Disable" |
| Remove item | Select item → click "Remove" (only shown when a deletable file exists) |
| Refresh | Click the Refresh button |
btmgr/
├── cmd/btmgr/
│ └── main.go # Entry point
├── internal/
│ ├── btm/
│ │ └── parser.go # sfltool/launchctl/pluginkit parsing & control
│ └── ui/
│ ├── app.go # Fyne UI
│ └── theme.go # Custom dark theme
├── Info.plist # macOS app bundle metadata
├── Makefile
└── go.mod
- Reading: Runs
sudo sfltool dumpbtm(falls back to without sudo) and parses the output into structuredItemobjects. Stale entries pointing to deleted files are filtered out automatically. - Status: Runs
launchctl print-disabled gui/<uid>for user services andlaunchctl print-disabled systemfor daemons to get the current enabled/disabled state. - Enable/Disable agents & daemons: Runs
launchctl enable/disable gui/<uid>/<id>orsystem/<id>. - Enable/Disable login items: Uses
pluginkit -e use/ignore -i <id>since Login Items are managed by BTM/pluginkit, not launchd. - Remove: Deletes the plist file (or
.appbundle) from disk and unloads the service vialaunchctl bootout. Operations requiring root (system daemons, paths outside~/) are batched into a single shell script executed with administrator privileges viaosascript.
sfltool dumpbtmrequires root; the app will try with and withoutsudo- Some items registered purely via SMAppService cannot be force-removed (only enabled/disabled)
- System-level daemons may require administrator credentials to control or remove
- Login Item enable/disable state changes via pluginkit are not immediately reflected in
sfltool dumpbtmoutput; the UI updates local state directly after toggling