Your clipboard, everywhere — private by design. Gancho is a local-first clipboard history and curated snippet library for Mac, iPhone, iPad, and the rest of the Apple platform family, built so future non-Apple clients can join without rewriting the core.
Gancho means “hook” in Spanish: it is where you hang everything you copy. And when something tiene gancho, it hooks you.
gancho.app · Releases · Changelog
Status: public v0.8.3, in active development toward 1.0. The capture engine, local
GRDB/SQLite storage with FTS5 search, the Liquid Glass history panel,
paste-back, pins and boards, the retention engine, the on-device intelligence
stack, the iPhone/iPad app and its extensions, iCloud sync via CKSyncEngine,
and StoreKit purchase plumbing are implemented and covered by tests. Serialized
purchase and restore automation verifies entitlement changes end to end. The
release/versioning lane ships a signed, notarized, stapled direct-download DMG,
a signed Sparkle appcast, version-sync guards, artifact QA, and the website. The
published v0.8.3 DMG is signed, notarized, stapled, and Gatekeeper-accepted.
The 0.8 series is the first direct release built against an embedded production CloudKit
and Push provisioning profile, so the artifact is sync-capable and its signed
entitlements are validated against the profile at package and QA time.
The v0.8.3 direct download can buy, activate, revalidate, and deactivate a Pro
license through Lemon Squeezy without embedding a payments secret. Pro unlocks
encrypted iCloud sync after the production schema and signed two-Mac candidate
matrix have been verified. What remains before 1.0 is App Store submission and
the account-gated launch pieces (App Store products and TestFlight).
- What's new in 0.8
- Product goal
- Platform plan
- Current capabilities
- Setup (< 10 min)
- Layout
- Privacy invariants
- Contributing
- Acknowledgements
- License
- Bring an existing history with you. A guided Mac import previews Maccy
archives or CSV files before writing, rejects protected and malformed rows,
deduplicates atomically, supports cancellation, and finishes with an exact
imported/skipped summary. Raycast is not currently an import source: its
documented clipboard API
exposes only six recent entries, while its
encrypted
.rayconfigbackup has no documented third-party decoding schema. Gancho does not inspect private encrypted app storage. - Give each local AI client only the context it needs. MCP access now uses expiring, revocable per-client grants with an explicit board/time context, independent read/write policy, fail-closed SQL filtering, and a content-free access ledger. No process can fall back to ambient history.
- Make first value visible without pre-consent tracking. Onboarding records only closed, content-free activation milestones locally; optional diagnostics receive one coarse aggregate only after explicit consent.
- See private reuse without creating another history. The Privacy Center on Mac, iPhone, and iPad shows bounded per-app capture, reuse, protected/ignored, and sensitive-expiry totals. The receipt stays on that device for 13 rolling months, never syncs or exports, and has an independent clear action.
- Make the Mac panel yours. Resize the history window freely or jump to a Compact, Standard, or Large preset; Gancho remembers the geometry and a Small, Standard, or Large semantic text preference across relaunches.
- Trust the failure paths, not just the happy one. In 0.8.3, clips shared into Gancho on iPhone and iPad wait sealed instead of as plaintext, a delete that fails locally is no longer sent to your other devices, sensitive clips on iPhone expire when you leave the app, and failed exports, purchases, and privacy settings on the Mac say so instead of looking like they worked.
Real macOS v0.8.3 build captured by XCUITest with synthetic fixtures. No user clipboard content or license key appears in the image.
Gancho should become the private memory layer for everything people copy and reuse. Its launch wedge can target developers and power users first, while the product language remains broad enough for anyone who repeatedly copies work between devices:
- Capture safely. Automatic on macOS, intentional on iOS/iPadOS/visionOS, with sensitive pasteboard markers vetoed before any content read.
- Retrieve instantly. Exact, fuzzy, and regex history search first; local semantic retrieval then grounds Q&A and smart organization.
- Reuse anywhere. Paste-back, snippets, templates, pins, and App Intents make captured work reusable without changing context.
- Sync without servers by default. Apple-platform sync uses the user's
iCloud account through a
SyncEngineboundary; future transports plug into the same boundary. - Earn trust visibly. No clipboard content in logs, telemetry, diagnostics, or error reports — ever.
| Platform | Role | Capture model |
|---|---|---|
| macOS | Primary creation surface | Automatic pasteboard monitoring with adaptive polling |
| iOS | Companion and capture surface | Share Extension, UIPasteControl, foreground actions, App Intents |
| iPadOS | Power companion | iPad-native navigation and keyboard workflows |
| visionOS | Apple ecosystem coverage | iPad-compatible build first; native spatial UI only if usage justifies it |
| watchOS | Lightweight viewer | Pins/recent items only; watchOS has no pasteboard API |
| Android / Windows / Linux | Future analysis only | Capability matrix and portable data envelope research; no implementation commitment yet |
The engineering rule is simple: platform-specific capture/UI code stays at the edges; models, privacy policy, storage/search contracts, sync, and intelligence stay in reusable modules.
Capture & privacy
- macOS pasteboard monitor: adaptive low-power polling, screen-lock and private-mode pause, own-write suppression, Universal Clipboard badge, rich payloads (text, RTF, HTML, image, file URLs), lossless bursts, off-main reads.
- Sensitive
org.nspasteboardtypes (ConcealedType,TransientType,AutoGeneratedType) veto capture before any content read; preloaded password-manager / banking denylist; "ignore next copy". - On-device sensitive-data detector (cards via Luhn; AWS/Stripe/GitHub/Slack keys; PEM keys; probable passwords) with masked previews and short expiry.
- Retention engine: global and per-kind expiry, sensitive auto-expire, pins exempt, background purge.
Storage & search
- GRDB/SQLite store with content-addressed disk blobs, lazy thumbnails, paged metadata-only lists, versioned migrations, device-aware dedup, and always-available JSON/CSV export.
- FTS5 full-text search (exact / fuzzy / regex; filters by kind, source app, date) with dedicated short-prefix indexes so fuzzy recall stays responsive while typing. The 100k-item performance harness measures cold startup and reproducible warm rounds separately.
- A 512-dimension on-device embedding index used by Ask your clipboard and auto-board suggestions. Main history search remains FTS5 exact/fuzzy/regex.
macOS app
- Menu-bar agent and resizable Liquid Glass floating panel (⇧⌘V): keyboard-first, type-to-search, composable source/kind/board/date filters, editable titles and explicit Save/Cancel text refinement, per-kind previews, a privacy-safe read-only full-content preview (⌘Y), paste-back via synthetic ⌘V (layout-aware keycodes, plain-text paste, restore-previous), onboarding, Settings, and the Privacy Center. Compact/Standard/Large geometry shortcuts and semantic text-size controls persist across relaunches.
- Pins and boards (multi-membership collections) and a unified Library for boards and snippets. Boards can use a fixed accessible color and an optional emoji identity that persists and syncs across Mac, iPhone, and iPad. A local, one-time suggestion offers to promote a clip to a snippet after its third successful reuse.
- Multi-selection via Shift or Command-click, with batch add-to-stack, add-to-board, and delete-with-Undo actions. Selected file clips drag together as independent file URLs when the whole selection is file-safe.
- Curated snippets and pins can be donated to Spotlight with structural redaction and a Settings switch that removes Gancho's system index immediately.
- Guided Maccy/CSV history import uses a read-only preview, source validation, atomic deduplication, cancellation, and a content-free final summary.
iPhone & iPad app
- Intentional capture only: Save button,
UIPasteControl, Share Extension, and App Intents / Shortcuts. Keyboard extension with history, widgets, iPad split view, source-app filtering, editable clip titles and text, and on-device enrichment of clips captured on the device.
On-device intelligence (zero network — every tier runs on the device)
- Deterministic tier-0 classifier — 17 kinds (URL, email, phone, address, date, color, JWT, JSON, UUID, code + language, credit card, tracking number, …) in under 5 ms.
- Apple Intelligence titles (fallback-safe), screenshot OCR, and semantic indexing for grounded Q&A and board suggestions — each behind a per-stage toggle on the Intelligence screen.
- Dev Actions (JWT decode, JSON pretty/minify, Base64, URL parse, color conversion, UUID formats), also exposed as App Intents.
- Smart Paste — rewrite a clip before pasting (summarize, fix grammar, change tone, key points), translate, and redact PII — all on-device and secret-safe.
- Ask your clipboard — grounded Q&A over history (semantic retrieval + the on-device model), with sensitive clips filtered out.
- Auto-board — suggest the board a clip belongs to from its semantic neighbors.
Sync & integrations
CKSyncEngineover the user's private iCloud database behind theSyncEngineboundary (clips, board membership, deletions) with a visible sync status. A real-device cross-device pass has completed; the matrix is repeated for each release candidate.ganchoCLI and a local, opt-in MCP server with expiring, revocable per-client grants, explicit board/time context, independent read/write permission, and a metadata-only access log, plus a VS Code "Save Selection" command — see docs/INTEGRATIONS.md.
Monetization & operations
- StoreKit 2 purchase / restore / entitlement plumbing with a contextual paywall and free-tier limits (the App Store products are owner-gated).
- Optional anonymous diagnostics, disabled until explicit consent and limited by type to metadata buckets; crash and support bundles remain content-free.
- Content-free activation milestones remain local before consent, and the independent private activity receipt exposes bounded per-app totals without syncing, exporting, or retaining clipboard content.
Engineering
- XcodeGen project; Swift 6 strict concurrency (app targets
@MainActor, engine-room targets nonisolated +Sendable); a bilingual (English + Spanish) String Catalog gate; accessibility (VoiceOver, Dynamic Type, reduce-transparency); and shared platform-neutral coordinators inGanchoAppCorebehind durable store and transport-neutral sync boundaries. - CI covers build/test/lint, an enforced production-source coverage floor, serialized StoreKit purchase/restore automation, and scale performance.
Prerequisites: macOS 15.4+ to run, Xcode 26+ to build, and
XcodeGen (brew install xcodegen).
git clone https://github.com/johnny4young/gancho.git
cd gancho
make hooks # install the pre-commit lint hook once per clone
make test # package unit tests (Swift Testing)
make open # generate Gancho.xcodeproj and open Xcode| Target | What it does |
|---|---|
make project |
Regenerate Gancho.xcodeproj from project.yml |
make build |
Build the macOS app (unsigned Debug) |
make build-ios |
Build the iOS app (unsigned Debug, generic device) |
make install-ios |
Build the iOS app team-signed and install it on the connected iPhone/iPad |
make test |
Run package unit tests |
make coverage |
Run package tests with coverage and enforce the production-source floor |
make test-storekit |
Run serialized StoreKit purchase/restore entitlement automation |
make test-ui / make test-ui-ios |
Run the macOS / iOS XCUITest suites |
make release-check |
Verify project.yml, CHANGELOG.md, and release templates are in sync |
make package-macos |
Build dist/Gancho-<version>.zip for release QA |
make qa-release |
QA the newest release ZIP, or ARTIFACT=/path/to/Gancho.app |
make site-check |
Verify the static website and its product-truth contract under site/ |
make format / make lint |
Format / verify Swift sources |
make hooks |
Install the versioned pre-commit lint hook |
make clean |
Remove generated project and build artifacts |
make open |
Generate and open the Xcode project |
The keyboard, widgets, and the "ready to paste" Live Activity only come alive on hardware. Plug in an iPhone/iPad, trust the Mac, then:
make install-ios # auto-detects the connected device
make install-ios IOS_DEVICE=<uuid> # or target one explicitly
make install-ios DEVELOPMENT_TEAM=<team-id>make install-ios team-signs the build (Xcode-managed provisioning, so the app
and its extensions get profiles on first run) and installs it with devicectl.
The Makefile defaults to the maintainer's development team, but forks and CI can
override DEVELOPMENT_TEAM without editing the file. Open Gancho on the device
from the Home Screen. List devices and their UUIDs with
xcrun devicectl list devices. After installing, enable the keyboard in
Settings → General → Keyboard → Keyboards → Gancho (turn on Full Access for clip
history), and Live Activities under the Gancho app's settings.
Release metadata is intentionally boring and synchronized:
project.ymlownsMARKETING_VERSIONandCURRENT_PROJECT_VERSION.CHANGELOG.mdkeeps[Unreleased]plus the newest released## [x.y.z]entry matchingMARKETING_VERSION.docs/releases/vX.Y.Z.mdcontains the curated, outcome-led GitHub Release body for the current version, including install/update instructions, availability limits, and verified artifact evidence..github/workflows/release.ymlgates taggedv*releases withmake release-check, lint, tests, macOS build, iOS build, packaging, and artifact QA before publishing the signed DMG, checksum, curated release note, Homebrew cask update, and signed appcast..github/workflows/pages.ymldeploys the landing fromsite/to Cloudflare Pages (https://gancho.app) and keeps the signed Sparkle appcast on GitHub Pages (https://johnny4young.github.io/gancho/appcast.xml, the app's feed URL).
See CHANGELOG.md and docs/RELEASING.md for the full release runbook, signing/notarization secrets, and manual QA checklist.
Apps/GanchoMac macOS menu-bar agent + Liquid Glass panel
Apps/GanchoiOS iPhone/iPad app (+ Share, keyboard, widgets)
site/ Cloudflare landing source + signed appcast source
CHANGELOG.md Release notes that must match MARKETING_VERSION
docs/releases/ Curated GitHub Release notes, one file per version
docs/RELEASING.md Release/versioning, signing, QA, and Pages runbook
docs/PRODUCT-TRUTH.md Tested matrix tying public claims to source evidence
Packages/GanchoKit One SwiftPM package — eight library products + a CLI:
GanchoKit models, GRDB store, retention, snippets, sync boundary
ClipboardCore pasteboard adapters, capture + intelligence policy
GanchoAI on-device classifiers, annotation, embeddings, QA
GanchoDesign shared design tokens and components
GanchoSync CKSyncEngine adapter (the only module importing CloudKit)
GanchoTelemetry metadata-only analytics transport (network-isolated)
GanchoAppCore shared platform-neutral application coordinators
GanchoMCP local MCP tools over the store boundary
gancho CLI + stdio MCP server
docs/ARCHITECTURE.md Engineering decisions and invariants
project.yml XcodeGen source of truth for Gancho.xcodeproj
Gancho.xcodeproj is generated and git-ignored. Change project.yml, then run
make project.
- Never store content tagged with
org.nspasteboard.ConcealedType,org.nspasteboard.TransientType, ororg.nspasteboard.AutoGeneratedType. - Never put clipboard content in logs, telemetry, crash reports, analytics, issue templates, or support bundles.
- The Privacy Center's activity receipt stores only per-day integer totals and validated, bounded app identifiers on that device, retains 13 rolling months, never syncs or exports, and can be cleared without deleting history.
- iOS, iPadOS, and visionOS use intentional capture only. No background pasteboard polling on those platforms.
- Any external model or transport must be opt-in per action and show exactly what would leave the device.
See docs/ARCHITECTURE.md for the full architecture and platform strategy.
Contributions are welcome — see CONTRIBUTING.md for the full
guide. In short: branch off main, keep the change coherent, open a PR against
main, and get CI green (macOS + iOS builds, package tests with an 80% coverage
floor, swift-format + SwiftLint, and the metadata/site/product-truth gates).
PRs squash-merge and their branch is deleted automatically on merge. Please read
the Code of Conduct; report security issues per the
Security Policy.
Gancho is built on excellent open-source work, including GRDB.swift and SQLCipher for encrypted local storage, KeyboardShortcuts for the global hotkey, Sauce for keyboard-layout handling, and TelemetryDeck for optional, explicitly enabled, content-free metrics.
MIT © 2026 Johnny Young.
