RepoPilotOpen in app →

DamascenoRafael/reminders-menubar

Simple macOS menu bar application to view and interact with reminders. Developed with SwiftUI and using Apple Reminders as a source.

Mixed

Single-maintainer risk — review before adopting

worst of 4 axes
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; top contributor handles 90% of recent commits…

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit today
  • 8 active contributors
  • GPL-3.0 licensed
Show 4 more →
  • Single-maintainer risk — top contributor 90% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/damascenorafael/reminders-menubar?axis=fork)](https://repopilot.app/r/damascenorafael/reminders-menubar)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/damascenorafael/reminders-menubar on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: DamascenoRafael/reminders-menubar

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/DamascenoRafael/reminders-menubar shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Single-maintainer risk — review before adopting

  • Last commit today
  • 8 active contributors
  • GPL-3.0 licensed
  • ⚠ Single-maintainer risk — top contributor 90% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live DamascenoRafael/reminders-menubar repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/DamascenoRafael/reminders-menubar.

What it runs against: a local clone of DamascenoRafael/reminders-menubar — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in DamascenoRafael/reminders-menubar | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>DamascenoRafael/reminders-menubar</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of DamascenoRafael/reminders-menubar. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/DamascenoRafael/reminders-menubar.git
#   cd reminders-menubar
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of DamascenoRafael/reminders-menubar and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "DamascenoRafael/reminders-menubar(\\.git)?\\b" \\
  && ok "origin remote is DamascenoRafael/reminders-menubar" \\
  || miss "origin remote is not DamascenoRafael/reminders-menubar (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "reminders-menubar/AppDelegate.swift" \\
  && ok "reminders-menubar/AppDelegate.swift" \\
  || miss "missing critical file: reminders-menubar/AppDelegate.swift"
test -f "reminders-menubar/Models/RemindersData.swift" \\
  && ok "reminders-menubar/Models/RemindersData.swift" \\
  || miss "missing critical file: reminders-menubar/Models/RemindersData.swift"
test -f "reminders-menubar/Models/ReminderItem.swift" \\
  && ok "reminders-menubar/Models/ReminderItem.swift" \\
  || miss "missing critical file: reminders-menubar/Models/ReminderItem.swift"
test -f "reminders-menubar/Extensions/EKReminder+Extensions.swift" \\
  && ok "reminders-menubar/Extensions/EKReminder+Extensions.swift" \\
  || miss "missing critical file: reminders-menubar/Extensions/EKReminder+Extensions.swift"
test -f "reminders-menubar/Models/ReminderList.swift" \\
  && ok "reminders-menubar/Models/ReminderList.swift" \\
  || miss "missing critical file: reminders-menubar/Models/ReminderList.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/DamascenoRafael/reminders-menubar"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Reminders MenuBar is a lightweight macOS menu bar application that provides quick access to Apple Reminders directly from the menu bar using SwiftUI and EventKit. It syncs with the native macOS Reminders app via iCloud and lets users view, create, edit, complete, and organize reminders without leaving the menu bar. Single Xcode project with main app in reminders-menubar/ directory, a separate launcher helper in reminders-menubar-launcher/ (standard pattern for menu bar apps to prevent dock appearance), and extensive Extensions folder (reminders-menubar/Extensions/) wrapping EventKit models (EKReminder, EKCalendar, EKRecurrenceRule) and native types (NSApplication, NSTableView, UserDefaults).

👥Who it's for

macOS users who frequently interact with reminders and want faster access without opening the full Reminders app; developers contributing to SwiftUI menu bar applications on macOS.

🌱Maturity & risk

Actively maintained with multi-language support (19+ locales), distributed via Homebrew and direct download, and requires macOS Big Sur 11+. The codebase is production-ready with proper entitlements and AppStore compatibility schemes, though exact CI/test coverage is not visible in the file listing.

Single-maintainer repository (DamascenoRafael) with no visible CI/test infrastructure in the file list, which introduces release validation risk. Dependency on Apple's EventKit framework and Reminders permission model means breaking changes in future macOS versions could require refactoring. No visible GitHub issues or PR metrics provided, making backlog assessment difficult.

Active areas of work

The repository shows active localization work (docs/adding-new-languages.md, 19 supported languages), recent Homebrew distribution setup (appcast.xml for updates), and AppStore compatibility tracks (two xcschemes: standard and AppStore variants). The swiftlint.yml config suggests code quality is being monitored.

🚀Get running

Clone with git clone https://github.com/DamascenoRafael/reminders-menubar.git, open reminders-menubar.xcodeproj in Xcode (no package manager install needed—native Xcode + SPM dependencies via Package.resolved), and run the 'Reminders MenuBar' scheme.

Daily commands: In Xcode, select scheme 'Reminders MenuBar' and press Cmd+R to build and run. The app will launch as a menu bar agent and request Reminders permission on first run.

🗺️Map of the codebase

  • reminders-menubar/AppDelegate.swift — Entry point for the macOS menu bar app; initializes the popover, manages app lifecycle, and handles menu bar status button interactions
  • reminders-menubar/Models/RemindersData.swift — Core data model that manages all reminder state, syncing with Apple EventKit, and provides the primary reactive data source for the UI
  • reminders-menubar/Models/ReminderItem.swift — Central domain model representing a single reminder; maps between EventKit's EKReminder and the app's internal state
  • reminders-menubar/Extensions/EKReminder+Extensions.swift — Bridges EventKit's EKReminder to the app's models; essential for translating Apple Reminders into app-compatible objects
  • reminders-menubar/Models/ReminderList.swift — Represents a reminder list/calendar; critical for organizing and filtering reminders by their containing list
  • reminders-menubar/AppCommands.swift — Defines global keyboard shortcuts and menu commands; centralized handler for app-wide user interactions
  • reminders-menubar/Constants.swift — Global configuration constants and user defaults keys; single source of truth for app settings and behavior

🛠️How to make changes

Add a new reminder property or computed field

  1. Add the property or computed var to ReminderItem struct in reminders-menubar/Models/ReminderItem.swift (reminders-menubar/Models/ReminderItem.swift)
  2. If the property maps from EKReminder, extend the initializer and/or add a helper in EKReminder+Extensions.swift (reminders-menubar/Extensions/EKReminder+Extensions.swift)
  3. If persisting back to EventKit, add save logic to RemindersData.swift (updateReminder or createReminder methods) (reminders-menubar/Models/RemindersData.swift)

Add a new filtering or sorting option

  1. Add a new enum case to RmbSortingOrder or create a new filter enum in reminders-menubar/Models/ (reminders-menubar/Models/RmbSortingOrder.swift)
  2. Add the sorting/filtering logic to PrioritizedReminders.swift or a method on RemindersData (reminders-menubar/Models/PrioritizedReminders.swift)
  3. Add the user setting key to Constants.swift and a toggle/picker in the UI layer (search for where RmbSortingOrder is accessed) (reminders-menubar/Constants.swift)

Add a new user preference or setting

  1. Define the UserDefaults key constant in reminders-menubar/Constants.swift (reminders-menubar/Constants.swift)
  2. Add a computed property getter/setter in UserDefaults+Extensions.swift for type-safe access (reminders-menubar/Extensions/UserDefaults+Extensions.swift)
  3. Use the extension property in RemindersData or UI code to read/write the preference (search for how existing prefs are accessed) (reminders-menubar/Models/RemindersData.swift)

Support a new date/time format or natural language input

  1. Add parsing or formatting logic to Date+Extensions.swift (reminders-menubar/Extensions/Date+Extensions.swift)
  2. If it involves string parsing, enhance String+Extensions.swift with helper methods (reminders-menubar/Extensions/String+Extensions.swift)
  3. Call the new helper from RemindersData when updating a reminder's due date (in updateReminder or createReminder) (reminders-menubar/Models/RemindersData.swift)

🔧Why these technologies

  • SwiftUI — Native macOS UI framework; declarative, reactive, and integrates seamlessly with AppKit for menu bar apps
  • EventKit (EKReminder, EKCalendar) — Official Apple framework for accessing and modifying the user's Reminders database; ensures sync with native Reminders app and respects system privacy
  • Combine (@Published, @ObservedObject) — Provides reactive data binding between RemindersData model and SwiftUI views; automatic UI updates on state changes
  • UserDefaults + @AppStorage — Standard macOS persistent storage for user preferences (sorting, filtering, UI state); lightweight and integrated with system settings

⚖️Trade-offs already made

  • Single RemindersData ObservedObject as the canonical data store

    • Why: Simplifies state management; avoids duplicate state across views; all UI reads/writes go through one source of truth
    • Consequence: Potential bottleneck if RemindersData becomes very large; would require refactoring into multiple view models for complex apps
  • Direct EventKit calls in RemindersData without a service layer

    • Why: Reduces boilerplate; EventKit is already Apple's official API, no need for an extra abstraction
    • Consequence: Hard to mock EventKit in tests; tight coupling to EventKit's concurrency model; future iOS port would require significant refactoring
  • Natural language date parsing in Date+Extensions (string-based heuristics)

    • Why: Lightweight; no external dependencies; provides user-friendly input
    • Consequence: Limited NLP capability; may not handle complex or ambiguous inputs; no machine learning fallback
  • Menu bar app only (no window or dock icon by default)

    • Why: Minimalist UX; stays out of the way; fits the 'quick glance' use case
    • Consequence: Limited discoverability; users must explicitly launch the app; no persistent window for reference

🚫Non-goals (don't propose these)

  • Does not sync reminders to a remote server or cloud service (EventKit-only; local or iCloud via system integration)
  • Does not support non-Apple reminders sources (Todoist, Microsoft To Do, etc.)
  • Does not provide real-time collaboration or sharing features
  • Does not run on iOS, iPadOS, or other platforms (macOS-only)
  • Does not include a dedicated task/project management UI beyond Reminders lists
  • Does not provide advanced reporting, analytics, or data export

🪤Traps & gotchas

macOS version lock: Requires Big Sur 11+ minimum; testing on older versions unsupported. Reminders permission: App silently fails if user denies Reminders access in System Settings > Privacy & Security > Reminders; no fallback UI. Launch agent complexity: The reminders-menubar-launcher target must be code-signed and included in the bundle; removing it will cause the app to appear in Dock. EventKit sync: Changes in iCloud state may not reflect immediately due to EventKit's asynchronous notification model; race conditions possible if multiple sync sources edit simultaneously.

🏗️Architecture

💡Concepts to learn

  • alin23/Lungo — macOS menu bar app using SwiftUI for quick action access; similar UI/UX pattern for menu bar integration
  • Mimestream/Mimestream-macOS — SwiftUI-based macOS menu bar application with persistent state and system tray integration
  • apple/swift-async-algorithms — EventKit relies on async/await patterns; this Swift concurrency library is a useful reference for handling reminder sync events
  • exelban/Stats — Mature multi-language macOS menu bar app using SwiftUI; reference for localization infrastructure at scale
  • insidegui/MusicBox — Menu bar app interacting with macOS native frameworks (Music/iTunes); similar EventKit-style framework integration pattern

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for ReminderItem model and EKReminder extensions

The repo has extensive model logic in reminders-menubar/Models/ReminderItem.swift and multiple EventKit extensions (EKReminder+Extensions.swift, EKRecurrenceRule+Extensions.swift, EKCalendar+Extensions.swift) that handle data transformation and business logic, but no visible test target. Adding unit tests for these models would catch regressions in reminder parsing, recurrence handling, and priority/sorting logic that directly impacts user experience.

  • [ ] Create a new test target 'reminders-menubarTests' in reminders-menubar.xcodeproj
  • [ ] Add unit tests in Tests/ directory for reminders-menubar/Models/ReminderItem.swift covering initialization and computed properties
  • [ ] Add tests for reminders-menubar/Extensions/EKReminder+Extensions.swift covering reminder status, priority, and date calculations
  • [ ] Add tests for reminders-menubar/Extensions/EKRecurrenceRule+Extensions.swift covering recurrence string formatting
  • [ ] Add tests for reminders-menubar/Extensions/RmbSortingOrder.swift to verify sorting logic correctness
  • [ ] Document test setup in docs/ for future contributors

Add GitHub Action workflow for SwiftLint enforcement on PRs

The repo has .swiftlint.yml configured but no CI workflow to enforce it. A .github/workflows/swiftlint.yml would automatically catch style violations before merge, maintaining code quality consistency and reducing reviewer overhead. This is a low-effort, high-value automation gap.

  • [ ] Create .github/workflows/swiftlint.yml workflow file
  • [ ] Configure the workflow to run SwiftLint on all .swift files in reminders-menubar/ and reminders-menubar-launcher/ directories
  • [ ] Set workflow to trigger on pull_request and push events
  • [ ] Add step to fail the workflow if any violations are found (strict mode)
  • [ ] Test the workflow locally or in a draft PR to ensure it catches real violations from .swiftlint.yml

Create comprehensive documentation for RemindersData model and data flow

reminders-menubar/Models/RemindersData.swift is the core state management model that orchestrates EventKit interactions and UI updates, but no dedicated documentation exists explaining the data flow, initialization sequence, or how it syncs with Apple Reminders. This is a frequent source of confusion for new contributors and would reduce onboarding friction significantly.

  • [ ] Create docs/data-flow-architecture.md explaining RemindersData lifecycle and responsibilities
  • [ ] Document the initialization sequence in AppDelegate.swift and how EventKit permissions are requested
  • [ ] Create a diagram or flow explanation of how reminders are fetched, cached, and updated in real-time
  • [ ] Document the relationship between RemindersData, ReminderList, ReminderItem, and RmbReminder models
  • [ ] Add code examples showing how to add a new reminder property and propagate it through the data flow
  • [ ] Link the new document from README.md in the Contributing section

🌿Good first issues

  • Add unit tests for extension methods: Files like reminders-menubar/Extensions/Date+Extensions.swift, EKRecurrenceRule+Extensions.swift, and ArrayReminderItem+Extension.swift have no visible test counterparts in the file list; testing natural language date parsing and recurrence rule formatting would improve robustness.
  • Improve localization completeness: The 19 languages listed in README suggest localization is extensive, but docs/images/add-localization-instruction.png suggests manual steps; create a CI workflow (GitHub Actions) to validate all .strings files are synchronized across all language variants.
  • Add menu bar icon theming: The app shows light/dark mode screenshots (reminder-menubar-light.png, reminder-menubar-dark.png) but no visible icon asset management in the file list; investigate and document menu bar icon rendering on Big Sur vs. Monterey/Ventura/Sonoma for consistency.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • d4452cd — Refactor private API access in EKReminder extension (DamascenoRafael)
  • 88e6f09 — Use new launch at login API on macOS 13.0+ (DamascenoRafael)
  • 67f12ad — Remove unnecessary self (DamascenoRafael)
  • a7feae7 — Refactor localization handling in rmbLocalized and rmbCurrentLocale (DamascenoRafael)
  • b741120 — Minor change in button style to use shorthand syntax (DamascenoRafael)
  • 23f7125 — Add debounce to notification publisher in RemindersData (DamascenoRafael)
  • 52e4a4d — Refactor authorization in RemindersService (DamascenoRafael)
  • d20ae78 — Refactor menu bar icon handling by moving logic into RemindersData (DamascenoRafael)
  • 5dc1986 — Add menu bar next reminder preview feature - Closes #217 (DamascenoRafael)
  • 1cd331b — Add "Menu Bar" settings tab (DamascenoRafael)

🔒Security observations

The application demonstrates reasonable security posture as a local-only macOS menu bar application using Apple's native EventKit framework. Primary risks relate to data persistence in UserDefaults (not encrypted), potential missing entitlements configuration, and lack of documented input validation. The application does not expose network-facing services or handle sensitive credentials. Recommendations focus on hardening UserDefaults usage, explicit entitlements documentation, and input validation implementation. No critical vulnerabilities were identified, and the use of EventKit as the data source significantly reduces injection attack risks.

  • Medium · Missing entitlements verification — reminders-menubar/Info.plist, reminders-menubar-launcher/reminders_menubar_launcher.entitlements. The application uses EventKit framework to access Apple Reminders without clear verification of entitlements implementation. The launcher app contains entitlements file, but main app entitlements configuration should be explicitly verified. Fix: Ensure the main application target has proper entitlements file (com.apple.security.automation, etc.) and verify entitlements are correctly signed. Document required privacy permissions.
  • Medium · Potential data persistence without encryption — reminders-menubar/Extensions/UserDefaults+Extensions.swift. The application uses UserDefaults for storing settings and preferences. UserDefaults is not encrypted by default on macOS and could expose sensitive user data like preferences, list selections, or display configurations if the system is compromised. Fix: Review what data is stored in UserDefaults. Consider using Keychain for sensitive data. Document the security implications of stored preferences.
  • Low · No visible input validation documentation — reminders-menubar/Extensions/String+Extensions.swift. While EventKit is used as the data source (reducing injection risk), there's no clear evidence of input validation in custom string extension files, particularly for parsing or formatting user-provided reminder data. Fix: Implement and document input validation for all user-provided data. Validate date strings, reminder titles, and other user inputs before processing.
  • Low · Missing code signing verification — reminders-menubar-launcher/, reminders-menubar.xcodeproj/. The presence of a launcher app (reminders-menubar-launcher) suggests the main application might use background launch mechanisms. Without visible code signing and notarization verification, this could be a security concern. Fix: Ensure the application and launcher are properly code-signed and notarized. Document the code signing process in contribution guidelines.
  • Low · No visible API/Network security configuration — reminders-menubar/. While the application primarily uses local EventKit data, there's no visible configuration for HTTPS enforcement, certificate pinning, or API security if future network features are added. Fix: If any network communication is implemented, use HTTPS with certificate pinning. Document API security practices.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · DamascenoRafael/reminders-menubar — RepoPilot