Guidelines for AI agents working in this repository.
spank is a macOS CLI tool that detects physical hits/slaps on Apple Silicon MacBooks via the accelerometer and plays audio responses. Single-file Go application with embedded MP3 assets.
- Platform: macOS on Apple Silicon (M2+) only
- Runtime requirement:
sudo(for IOKit HID accelerometer access) - Architecture: Single
main.gofile with embedded audio assets
# Build
go build -o spank .
# Run (requires sudo)
sudo ./spank
sudo ./spank --sexy # escalating responses mode
sudo ./spank --halo # Halo death sounds mode
sudo ./spank --custom /path/to/mp3s # custom audio directorygo install github.com/taigrr/spank@latestReleases are automated via GitHub Actions + GoReleaser Pro when a v* tag is pushed:
git tag v1.0.0
git push origin v1.0.0spank/
├── main.go # All application code (single file)
├── audio/
│ ├── pain/ # Default "ow!" responses (10 MP3s)
│ ├── sexy/ # Escalating responses (60 MP3s)
│ └── halo/ # Halo death sounds (9 MP3s)
├── go.mod
├── .goreleaser.yaml # Release configuration
└── .github/workflows/ # CI/CD
| Package | Purpose |
|---|---|
github.com/taigrr/apple-silicon-accelerometer |
Reads accelerometer via IOKit HID |
github.com/gopxl/beep/v2 |
Audio playback (MP3 decoding, speaker output) |
github.com/spf13/cobra |
CLI framework |
github.com/charmbracelet/fang |
CLI config/execution wrapper |
Audio files are embedded at compile time using //go:embed:
//go:embed audio/pain/*.mp3
var painAudio embed.FSTwo playback strategies in playMode:
modeRandom: Random file selection (pain, halo, custom modes)modeEscalation: Intensity increases with slap frequency (sexy mode)
sensor.Run()reads accelerometer in background goroutine- Data shared via
shm.RingBuffer(POSIX shared memory) detector.New()processes samples with vibration detection algorithms- Events trigger audio playback with 750ms cooldown
speakerMu sync.Mutexprotects speaker initializationslapTracker.mu sync.Mutexprotects slap scoring state- Audio playback runs in goroutines (
go playAudio(...))
Key tuning parameters in main.go:
| Constant | Value | Purpose |
|---|---|---|
decayHalfLife |
30s | How fast escalation fades |
slapCooldown |
750ms | Minimum time between audio plays |
sensorPollInterval |
10ms | Accelerometer polling rate |
maxSampleBatch |
200 | Max samples processed per tick |
-
Root required: The app must run with
sudofor IOKit HID access. Therun()function checksos.Geteuid() != 0. -
Apple Silicon only: Only builds for
darwin/arm64. Intel Macs are not supported. -
Private dependency:
github.com/taigrr/apple-silicon-accelerometerrequiresGOPRIVATEsetting and GitHub PAT for CI. -
Single file: All code is in
main.go. When adding features, follow the existing pattern of types and functions in the same file. -
Mutually exclusive modes:
--sexy,--halo, and--customflags cannot be combined. -
CGO disabled: Builds use
CGO_ENABLED=0despite targeting macOS.
To add a new sound pack:
- Create directory under
audio/ - Add MP3 files (numbered for escalation mode, any names for random)
- Add
//go:embed audio/newpack/*.mp3variable - Add flag and case in
run()switch statement - Create
soundPackwith appropriateplayMode
Version is injected via ldflags at build time:
var version = "dev"GoReleaser sets -X main.version={{.Version}} during release builds.