A native macOS application for managing launchd agents and daemons — built with SwiftUI.
✅ Signed & notarized — installs without Gatekeeper warnings.
Taktwerk provides a clean GUI for browsing, editing, loading, and unloading launchd jobs across all standard directories on macOS. It's designed for developers and power users who work with launchd configuration files regularly.
- Browse all launchd sources — User Agents, Global Agents, User Daemons, Global Daemons
- Visual plist editor — Edit job properties (label, program, schedule, environment, etc.) through a structured form
- Raw XML editor — Switch to raw XML with live validation and Apple's
plutillint integration - Two-way sync — Changes in the form reflect in XML and vice versa
- Load / Unload — Control launchd jobs directly from the UI
- Custom tags — Organize jobs with colored tags; filter by tag or source
- Filter status bar — Always see which filters are active
- Settings — Configure default view filters, manage tag definitions with rename support
- Refresh — Re-scan launchd directories to pick up external changes
- macOS 26 (Tahoe) or later
- Xcode 26+
- Swift 6.2+
# Install XcodeGen (if not already installed)
brew install xcodegen
# Generate the Xcode project
xcodegen generate
# Open in Xcode
open Taktwerk.xcodeprojBuild and run from Xcode (⌘R).
Note: Taktwerk requires access to launchd directories and the
launchctlbinary. It runs without App Sandbox and uses Hardened Runtime.
Taktwerk/
├── Models/ # Domain models (LaunchdJob, PlistConfig, TagStore, etc.)
├── Services/ # Actor-based services (LaunchctlService, PlistService, LogService)
├── Features/ # Feature modules (JobList, JobDetail, JobEditor, Settings)
├── Shared/ # Reusable views and extensions
└── Resources/ # Bundled resources
TaktwerkTests/ # Unit tests (Swift Testing)
project.yml # XcodeGen project specification
- MVVM with
@ObservableViewModels - Actor-based services for thread-safe system interaction
- Zero third-party dependencies — pure Foundation + SwiftUI
- Swift Testing for unit tests
xcodebuild -project Taktwerk.xcodeproj -scheme Taktwerk -configuration Debug testTaktwerk uses semantic versioning driven by Git tags.
Creating a release:
git tag v1.2.0
git push origin v1.2.0This triggers the release workflow which builds a signed, notarized DMG and publishes it as a GitHub Release.
Version numbers:
CFBundleShortVersionString= tag version (e.g.,1.2.0)CFBundleVersion= CI build number (auto-incremented)
| Workflow | Trigger | What it does |
|---|---|---|
| CI | Push to main, PRs |
Build + test |
| Release | v* tags |
Build → sign → DMG → notarize → GitHub Release |
Both workflows run on a self-hosted macOS runner (macOS 26 + Xcode 26 required).
The CI/CD pipeline requires a self-hosted GitHub Actions runner on a macOS 26 (Tahoe) machine with Apple Silicon.
Prerequisites on the runner machine:
# Install Xcode 26 from the Mac App Store or Apple Developer portal
# Then accept the license:
sudo xcodebuild -license accept
# Install XcodeGen
brew install xcodegen
# Verify
xcode-select -p # Should point to Xcode 26
xcodegen --versionRegister the runner:
- Go to your GitHub repo → Settings → Actions → Runners → New self-hosted runner
- Select macOS and ARM64
- Follow the download and configuration steps shown on the page:
# Download (URL from GitHub UI)
mkdir actions-runner && cd actions-runner
curl -o actions-runner.tar.gz -L <download-url>
tar xzf actions-runner.tar.gz
# Configure
./config.sh --url https://github.com/<owner>/Taktwerk --token <token>
# When prompted for labels, add: self-hosted,macOS,ARM64
# Install as a service (runs on boot)
sudo ./svc.sh install
sudo ./svc.sh startRequired GitHub Secrets (repo → Settings → Secrets and variables → Actions):
| Secret | Description |
|---|---|
APPLE_CERTIFICATE_P12 |
Base64-encoded Developer ID Application .p12 certificate |
APPLE_CERTIFICATE_PASSWORD |
Password for the .p12 file |
APPLE_TEAM_ID |
Apple Developer Team ID (10-char alphanumeric) |
APPLE_ID |
Apple ID email for notarization |
APPLE_ID_PASSWORD |
App-specific password for the Apple ID |
KEYCHAIN_PASSWORD |
Any random string (used for a temporary build keychain) |
Exporting your Developer ID certificate:
# In Keychain Access: find "Developer ID Application: <Your Name>"
# Right-click → Export → save as .p12 with a password
# Then base64-encode it:
base64 -i certificate.p12 | pbcopy
# Paste into the APPLE_CERTIFICATE_P12 secretOliver Lohmann
