Gutta is a tiny, offline task list for the Mac menu bar. Type a task the way you would say it, press Return, and get back to what you were doing.
- Lives in the menu bar and shows overdue, today, and later counts.
- Starts automatically when you log in to your Mac.
- Opens as a centered quick panel with Command–Shift–Space.
- Understands phrases such as
buy bread tomorrow morning,call mom at 5pm, andsend the invoice Friday at 10:30. - Turns semicolon-separated input into multiple tasks.
- Sends local reminders for timed tasks, with a global default and per-task overrides.
- Supports search, completion, and deletion without leaving the keyboard.
- Stores tasks locally with SwiftData and can sync them through a folder in the user's own iCloud Drive. There are no Gutta accounts, third-party servers, or location features.
Folder sync uses each person's own iCloud Drive account. Gutta never uploads tasks to a developer-owned account or service.
- Click the iCloud button in Gutta's bottom bar and choose Choose Sync Folder.
- Create or select a folder in iCloud Drive, such as
Gutta. - On every other Mac signed in to the same iCloud account, choose that same iCloud Drive folder in Gutta once.
The folder permission is saved as a security-scoped bookmark, so Gutta resumes sync automatically after future launches. Choosing Stop Syncing removes that Mac's saved folder permission without deleting local tasks or anything in the selected folder.
Gutta keeps its SwiftData database local and exchanges one JSON record per task
inside a Gutta Sync Data subfolder. This avoids putting a live database in a
file-sync service. Adds, completions, reminder changes, and deletions are merged
while Gutta is running; offline changes catch up when iCloud Drive reconnects.
If the same task changes concurrently, the most recently edited copy wins.
Folder selection is required once per Mac because the App Sandbox doesn't let an app silently access arbitrary iCloud Drive folders. Folder sync also works with other services that expose a normal Finder folder, such as Dropbox or OneDrive.
- Open
gutta.xcodeprojin Xcode. - Select the
guttascheme and your Mac as the destination. - Run the app. Its checkmark appears in the menu bar; it intentionally does not add a Dock icon.
Gutta targets macOS 14 or newer.
Buy bread tomorrow morning
Call mom tonight at 8
Send the report Friday at 10:30
Book tickets tomorrow; email Alex at 4pm
Tasks without scheduling details default to today, and date-only tasks stay
date-only. Words such as morning, afternoon, and evening add sensible
default times, while an exact time always wins.
Use the bell in the bottom bar to choose the default reminder: 15, 20, or 30 minutes, one hour, two hours, or off. Timed tasks use that default automatically. Use the bell beside an individual timed task to keep the default, choose a different lead time, or turn its reminder off. Gutta asks for macOS notification permission only when it has a future reminder to schedule.
Gutta uses Sparkle to check the latest stable GitHub release automatically. The arrow-in-a-circle button in the bottom bar also starts a manual check. When an update is available, Sparkle shows its standard release window and handles the signed download, installation, and relaunch after the user clicks Install Update.
The feed URL uses GitHub's releases/latest route, which excludes draft and
prerelease releases. Every stable release must therefore include these assets:
Gutta-<version>-macOS-arm64.zip, containing onlyGutta.app.appcast.xml, signed with Gutta's Sparkle EdDSA key.Gutta-<version>-macOS-arm64.dmgfor first-time installation.SHA256SUMS.txtfor artifact verification.
Every push to main, including merged pull requests and direct commits, runs the
Release macOS GitHub Actions workflow. It increments the patch version from the
latest stable tag, builds and verifies an arm64 Release archive, creates an
annotated tag, generates changelog notes from the commits since the previous
release, and publishes the DMG, Sparkle ZIP, signed appcast, and checksums.
The workflow publishes through a draft so a partially uploaded release never becomes visible to Sparkle. Concurrent pushes are queued and workflow reruns are idempotent for a commit that already has a published release.
The repository must have a SPARKLE_PRIVATE_KEY Actions secret containing the
private key exported by Sparkle's generate_keys -x tool. The key is passed
directly to generate_appcast and is never written into the repository.
-
Increment both
MARKETING_VERSIONandCURRENT_PROJECT_VERSIONin the Xcode target, then archive and export the app. The build number must always increase. -
Put only the exported
Gutta.appin the update ZIP. Keep the existing ZIP filename convention, such asGutta-0.0.4-macOS-arm64.zip. -
Generate the signed feed beside the ZIP:
scripts/generate-appcast.sh v0.0.4 ./Gutta-0.0.4-macOS-arm64.zip
The script finds Sparkle's tools from Xcode's resolved package. Set
SPARKLE_BIN_DIR=/path/to/Sparkle/binif the package artifacts live elsewhere. -
Create the GitHub release as a draft, upload the ZIP,
appcast.xml, DMG, and checksums, then publish it only after every asset is present. Mark beta or test releases as prereleases so installed stable builds ignore them.
Sparkle's private EdDSA key is stored in the release Mac's login Keychain under
the default ed25519 account. Back it up securely with Sparkle's generate_keys -x command. Never commit or attach the private key. The matching public key is
embedded in the app and cannot be replaced casually once updater-enabled builds
have shipped.