Caloura is a fast macOS menu-bar screenshot tool for area, window, and full-screen capture.
- Area, window, and full-screen capture (multi-display aware)
- Smart crop + OCR pipeline
- Annotation and pinning workflows
- Searchable history with encrypted-at-rest payload storage
- Sparkle-based in-app updates for direct distribution
Caloura now uses an install-first onboarding flow:
- Install the app in
/Applicationsbefore setup continues - Launch the installed copy and take the first screenshot
- Grant Screen Recording only when the first real capture needs it
Permission behavior:
- Screen Recording is checked in context when capture starts
- If Screen Recording already looks enabled, onboarding silently validates it in the background and keeps the first-capture CTA as the primary action
- Return from System Settings triggers an automatic re-validation loop that trusts live ScreenCaptureKit validation before stale CoreGraphics state, then resumes the pending first capture on success
- If macOS still stays ambiguous after the post-Settings grace window, Caloura performs one automatic relaunch and resumes the pending first capture on the next launch
- Stored history about a previously working app copy is advisory only; if the Screen Recording record is gone, Caloura still issues a real system permission request so the app reappears in System Settings
- The repaired/completed permission UI is only shown after a live validation path succeeds; stale CG for the same app copy stays in validation/repair instead of pretending capture is ready
- Stale permission records are treated as a separate repair state from plain denial, but only after a real capture validation path fails
- Accessibility remains deferred to Scroll Capture only
If capture fails after permission looks enabled:
- Use only one installed copy while testing (
/Applications/Caloura.apprecommended). - In System Settings > Privacy & Security > Screen & System Audio Recording, ensure the current build is enabled.
- Return to Caloura and let the automatic re-validation finish. Caloura will relaunch itself once if macOS still keeps stale in-process state.
- If Caloura says permission needs validation for this installed copy, run the in-app live check again instead of trusting the passive toggle alone.
- If the first capture still fails after the automatic retry/relaunch, use the in-app repair flow or run
scripts/permission_diagnose.sh.
macOS can treat different signatures/paths as separate apps. If permission seems granted but capture still fails:
- Prefer
/Applications/Caloura.appfor public validation. - Re-grant permission for the exact build you launched only after a real capture attempt fails.
- License state: persisted locally for frictionless runtime (no startup keychain prompt path).
- History payload: encrypted with AES-GCM at
~/Library/Application Support/Caloura/history.enc - History key: the root key is stored in the macOS Keychain
(device-only, non-syncing, available after first unlock — no interactive
prompt). A file-backed key under
~/Library/Application Support/Caloura/security/history.keyis used only in DEBUG/test builds via a test override, never in release. - Permission model: Screen Recording is the only required OS permission.
Ctrl+Shift+4Capture AreaCtrl+Shift+5Capture WindowCtrl+Shift+3Capture Full ScreenCtrl+Shift+RRepeat Last Area
All shortcuts are configurable in Preferences.
- macOS 26.0+ (Tahoe)
- Xcode 26 (for local development)
xcodegen generate
xcodebuild build -project Caloura.xcodeproj -scheme Caloura -configuration Debug
xcodebuild test -project Caloura.xcodeproj -scheme Caloura -configuration DebugThe CI Checks workflow runs on every PR and push to main: SwiftPM build,
SwiftLint, swift test, then xcodebuild test (skipping only
CalouraUITests, which needs a signed, TCC-authorized host app). The Xcode
test step passes CODE_SIGNING_ALLOWED=NO because runners have no signing
identity; never use that flag for local manual launch/testing.
The version-controlled pre-commit hook (.githooks/pre-commit) runs the
banned-suppression scan, swiftlint --strict on staged files, swift build,
and swift test. Activate it once per clone with
git config core.hooksPath .githooks. It is a fast subset of CI (the workflow
above is authoritative); run the full xcodebuild test suite on a
TCC-authorized machine before pushing.
The Release Smoke workflow exercises the signed packaging path (build,
codesign, notarize, staple, quarantined launch) end-to-end on every tagged
release.
Versioning is gated by scripts/release.sh:
- tag/version alignment (
RELEASE_TAG/GITHUB_REF_NAME) - exported app version parity
- final ZIP artifact version parity
- final DMG artifact version parity
- signed/notarized/stapled manual-download DMG plus Sparkle ZIP
Guard-only check:
RELEASE_GUARD_ONLY=1 RELEASE_TAG=v<version> ./scripts/release.sh <version>For the public website/appcast release flow (current version: see MARKETING_VERSION in project.yml), use:
- app build + notarization:
scripts/release.sh - manual-download DMG publish + Sparkle ZIP publish:
scripts/publish.sh - public artifact verification:
scripts/public_download_qa.sh --version <version> verify - local pre-release validation stays in
scripts/release_ready.sh - live appcast validation happens in
scripts/publish.shafter the site repo is updated Release SmokeGitHub Actions runs the signed packaging flow on a pinned Xcode runner before publish
Use the runbook in tasks/public-download-qa-runbook.md for full public download, onboarding, permission, and trial checks.
Quarantine is preserved by default so Gatekeeper behavior stays visible; set STRIP_QUARANTINE=1 only when you explicitly want a local-only install without quarantine.
Proprietary software.