ChimeAlert
ADHD-friendly, impossible-to-miss full-screen alert system for macOS. Extracted from Chime app.
Install / Use
/learn @uxderrick/ChimeAlertREADME
ChimeAlert
A full-screen alert system for macOS with multi-monitor support, keyboard shortcuts, and extensive customization options.
Features
- Full-screen alerts with animated pulsating border
- Multi-monitor support (all monitors, primary only, external only, or mouse location)
- Sleep/wake recovery handling to prevent UI freezing
- Keyboard shortcuts (⌘S snooze, ⌘↩ action, Esc dismiss)
- Sound playback with 5 bundled sounds and rotation support
- Highly customizable (colors, animations, timings, sounds)
- Snooze management with configurable limits
- Delegate pattern for analytics and custom behavior
- Multiple alert types (meetings, reminders, tasks, custom)
Installation
Swift Package Manager
Add ChimeAlert to your Package.swift dependencies:
dependencies: [
.package(url: "https://github.com/uxderrick/ChimeAlert.git", from: "1.0.0")
]
Or in Xcode:
- File → Add Package Dependencies
- Enter repository URL:
https://github.com/uxderrick/ChimeAlert.git - Select version and add to target
Quick Start
1. Conform Your Model to AlertItem
import ChimeAlert
import Foundation
struct MyMeeting: AlertItem {
var id: String
var title: String
var startTime: Date
var endTime: Date
var notes: String?
var actionURL: URL? // Optional action URL (e.g., Zoom link)
var actionButtonTitle: String? { actionURL != nil ? "Join" : nil }
var attendees: [AlertAttendee]?
var isRecurring: Bool
var recurrenceDescription: String?
var priority: AlertPriority { .high }
var type: AlertType { .meeting }
}
2. Configure AlertManager
import ChimeAlert
// Configure global settings
AlertManager.shared.configuration.soundVolume = 0.9
AlertManager.shared.configuration.maxSnoozeAttempts = 5
AlertManager.shared.monitorPreference = .allMonitors
3. Show an Alert
let meeting = MyMeeting(
id: "meeting-123",
title: "Q4 Planning Meeting",
startTime: Date().addingTimeInterval(300), // 5 minutes from now
endTime: Date().addingTimeInterval(3900), // 1 hour later
notes: "Discuss roadmap and budget",
actionURL: URL(string: "https://zoom.us/j/123456789"),
attendees: [
AlertAttendee(name: "Alice Chen", isOrganizer: true),
AlertAttendee(name: "Bob Smith")
],
isRecurring: false,
recurrenceDescription: nil
)
AlertManager.shared.showAlert(for: meeting)
Configuration
Visual Customization
// Pulsating border
AlertManager.shared.configuration.borderColors = [.red, .orange]
AlertManager.shared.configuration.pulseDuration = 1.5
// Type-specific gradients
AlertManager.shared.configuration.meetingGradient = [
Color(red: 0.2, green: 0.4, blue: 0.8),
Color(red: 0.1, green: 0.2, blue: 0.6)
]
// Animation speeds
AlertManager.shared.configuration.glowDuration = 3.0
AlertManager.shared.configuration.entranceAnimationDuration = 0.5
Sound Configuration
// Enable/disable sound
AlertManager.shared.configuration.soundEnabled = false
// Volume (0.0 to 1.0)
AlertManager.shared.configuration.soundVolume = 0.5
// Sound rotation
AlertManager.shared.configuration.rotateSounds = false
Snooze Behavior
// Default snooze duration (seconds)
AlertManager.shared.configuration.defaultSnoozeInterval = 300 // 5 minutes
// Available snooze options
AlertManager.shared.configuration.snoozeOptions = [60, 300, 600, 1800]
// Maximum snooze attempts before disabling snooze button
AlertManager.shared.configuration.maxSnoozeAttempts = 5
Multi-Monitor Configuration
// Show on all monitors
AlertManager.shared.monitorPreference = .allMonitors
// Show on primary monitor only
AlertManager.shared.monitorPreference = .primaryOnly
// Show on external monitors only
AlertManager.shared.monitorPreference = .externalOnly
// Show on monitor where mouse cursor is located
AlertManager.shared.monitorPreference = .mouseLocation
Delegate Integration
Implement AlertDelegate to handle lifecycle events, track analytics, and customize behavior:
@MainActor
class MyAlertDelegate: AlertDelegate {
func alertDidShow(_ item: AlertItem) {
// Track alert display
Analytics.track("alert_shown", properties: ["title": item.title])
}
func alertDidTapAction(_ item: AlertItem) {
// Handle action button tap (Join/Complete/Open)
if let url = item.actionURL {
NSWorkspace.shared.open(url)
}
}
func alertDidSnooze(_ item: AlertItem, duration: TimeInterval) {
// Track snooze action
Analytics.track("alert_snoozed", properties: ["duration": duration])
}
func alertShouldTrackStats() -> Bool {
return true // Enable internal stat tracking
}
func alertDidTrackStat(event: String, properties: [String: Any]) {
// Forward to your analytics system
Analytics.track(event, properties: properties)
}
func alertShouldShow(_ item: AlertItem) async -> Bool {
// Optional: Validate if alert should still be shown
// Useful for checking external state (e.g., task deleted)
return true
}
}
// Set the delegate
AlertManager.shared.delegate = MyAlertDelegate()
Alert Types
ChimeAlert supports multiple alert types with different visual styling:
Meeting (Blue Gradient)
struct Meeting: AlertItem {
var type: AlertType { .meeting }
// Blue/green gradient, "Join" button, shows attendees
}
Reminder (Purple Gradient)
struct Reminder: AlertItem {
var type: AlertType { .reminder }
// Purple gradient, "Complete" button
}
Task (Red Gradient)
struct Task: AlertItem {
var type: AlertType { .task }
// Red gradient, "Complete" button
}
Custom
struct CustomAlert: AlertItem {
var type: AlertType {
.custom(
gradient: [
ColorComponents(red: 1.0, green: 0.5, blue: 0.0),
ColorComponents(red: 0.8, green: 0.3, blue: 0.0)
],
iconName: "star.fill"
)
}
}
Advanced Features
Trial Badge (Optional)
Display a countdown badge for trial periods:
AlertManager.shared.configuration.trialBadge = TrialBadgeInfo(
text: "7d trial left",
color: Color.orange
)
// Remove badge
AlertManager.shared.configuration.trialBadge = nil
Sleep/Wake Recovery
ChimeAlert automatically handles system sleep/wake transitions. To integrate with your app's sleep monitoring:
func setupSleepWakeNotifications() {
NSWorkspace.shared.notificationCenter.addObserver(
forName: NSWorkspace.willSleepNotification,
object: nil,
queue: .main
) { _ in
AlertManager.isSystemRecovering = true
}
NSWorkspace.shared.notificationCenter.addObserver(
forName: NSWorkspace.didWakeNotification,
object: nil,
queue: .main
) { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
AlertManager.isSystemRecovering = false
}
}
}
Attribution
This library displays a "Powered by Chime" badge in the bottom-right corner of all alerts. The badge links to usechime.app when clicked.
Badge removal is only available with a commercial license. See Commercial Licensing for details.
Requirements
- macOS 13.0 (Ventura) or later
- Swift 5.9 or later
- Xcode 15.0 or later (for development)
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure
swift testpasses - Submit a pull request
Commercial Licensing
The open-source version of ChimeAlert requires the "Powered by Chime" attribution badge to remain visible in all deployments. If you need to use ChimeAlert in a commercial application, you must purchase a commercial license.
Why Purchase a Commercial License?
- ✅ Remove the attribution badge - Display your own branding without "Powered by Chime"
- ✅ Professional appearance - No third-party branding in your commercial products
- ✅ Perpetual license - One-time payment, use forever (no recurring fees)
- ✅ Unlimited applications - Use in as many commercial products as you want
- ✅ Support development - Help maintain and improve ChimeAlert
Pricing
<table> <thead> <tr> <th width="150">Tier</th> <th width="120">Price</th> <th>Best For</th> </tr> </thead> <tbody> <tr> <td><strong>Indie License</strong></td> <td><strong>$99</strong> USD</td> <td>Solo developers, indie projects, and businesses with <strong><$100K annual revenue</strong></td> </tr> <tr> <td><strong>Enterprise License</strong></td> <td><strong>$499</strong> USD</td> <td>Companies with <strong>≥$100K annual revenue</strong>, agencies, and teams</td> </tr> </tbody> </table>Both tiers include:
- Badge removal for all your commercial applications
- Perpetual license (use forever)
- All future updates
- Email support
How to Purchase
Contact us at usechimeapp@gmail.com with:
- Your tier - Indie or Enterprise
- Company/individual name - For the license certificate
- Use case (optional) - What you're building with ChimeAlert
We'll send you an invoice and license certificate within 1 business day.
License
ChimeAlert is released under the MIT License.
This means:
- ✅ Free for everyone - personal and commercial use allowed
- ✅ Modify and distribute - create derivative works freely
- ✅ No restrictions - use in any projec
Related Skills
node-connect
346.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
