Everything you reuse, one keystroke away.
FastΒ Β Β·Β Β
PrivateΒ Β Β·Β Β
On-deviceΒ Β Β·Β Β
Keyboard-first
summon.technology β or build from source
Narrower on purpose. Summon is not a notes app β it isn't where you write. It's not a file manager β it isn't where you keep everything. It holds only the handful of things you reach for again and again: the canned reply, the portfolio PDF, the VAT number, the headshot. Because it holds less, it can be much better at the one moment that matters β getting one of them to where your cursor already is.
One keystroke, wherever you are. Press β₯Space in any app, type a few characters, press β©, and the thing lands in the app you were already using. No window to find, no tab to switch to, no clipboard to babysit. The panel appears over your work and disappears again.
Private by construction. There is no account, no telemetry, and no server of ours: sync runs through your iCloud, performed by the system, and nothing ever reaches the developer. Anything you mark sensitive is encrypted with AES-GCM under a key wrapped by your PIN and a secret that never leaves the device, so a locked item stays findable by name while revealing nothing of its contents, its file, or even its OCR'd text. Turn on Encrypt everything and that applies to the whole library, including what syncs. What you do not seal crosses iCloud like the rest of your iCloud data, which Apple can read unless you have Advanced Data Protection on β a trade worth knowing about rather than a claim worth overstating.
Fast, and measured rather than claimed. A keystroke re-ranks 2,000 items in 0.55 ms. Those numbers are asserted by the test suite against budgets that fail the build β because the first time performance was "fixed" here, the benchmark and the app disagreed about what was being measured, and nobody noticed for a whole commit.
|
β₯Space from any app, type a few letters, β©. It pastes into whatever you were just using. Fuzzy search, ranked by what you actually reach for. |
Text, rich text, images, PDFs, whole files. Dropped in, copied in, or grabbed from your selection without leaving the app you're in. |
What you saved is what gets pasted. Formatting survives where the app you paste into can take it; |
|
Nested folders you drag to rearrange, each with its own icon and colour. Plus tags, pins, and a search that reaches inside PDFs. |
Mark anything sensitive and it's encrypted at rest. Titles stay searchable; contents don't. Unlock with a PIN or Touch ID, auto-lock on a timer. |
No account, no analytics, no server of ours. Sync is your own iCloud, and sensitive items cross it encrypted with a key Apple never sees. |
Press β₯Space and the panel appears over whatever you're doing without disturbing it. Before you type anything it shows what you're most likely to want: things you've pinned, then things you've used recently. If you've used an item in this app before, a section named for that app comes first β so Mail surfaces your canned replies and Finder surfaces your documents.
Type, and results are ranked by a fuzzy match, by how often and how recently you've used each item, and by whether you've used it in this app before. The characters that matched are picked out in the title, so it's always clear why a result is in the list.
β© pastes it where your cursor already was. ββ© copies instead, β₯β© opens the file, β§β© pastes as plain text, and β1ββ9 jump straight to a result.
Four ways, because the friction of saving is what decides whether a tool like this gets used at all:
- Drag and drop files onto the panel, the library, or a specific folder.
- β₯β§S saves whatever is selected right now, without leaving the app you're in. In Finder it reads the selection directly; elsewhere it copies, reads the pasteboard, and puts your previous clipboard contents back.
- Clipboard history keeps the last 40 things you copied so you can promote one into the library. It skips anything a password manager marks as concealed, and ignores 1Password, Bitwarden and Keychain Access entirely.
- "Add to Summon" registers in the system Services menu, so it appears in the right-click menu of every app.
Folders nest as deep as you like and rearrange by dragging β drop onto a folder to nest inside it, between two to reorder. Each gets its own icon and colour from a curated set of about ninety SF Symbols, searchable by meaning rather than by name: "money" finds the currency symbols, "vat" finds percent, "password" finds the key.
Tags cut across folders, pins float things to the top, and filters can be typed inline: #tag, /folder, img:, pdf:, txt:, file:, pinned:, locked:.
βK opens every action for the selected item, searchable, with each shortcut beside it: paste, paste as plain text, copy, open, reveal in Finder, rename, move to folder, add tag, pin, mark sensitive, delete.
It exists in the panel and only in the panel. A window has room to show its actions, so the library shows them rather than hiding them a level down.
Mark an item or a whole folder sensitive and its contents are encrypted at rest:
- A random 256-bit master key is generated once. Per-item keys derive from it via HKDF using the item's own UUID, so no key is ever reused across two items.
- That master key is wrapped twice β under your PIN with PBKDF2-SHA256 at 600,000 iterations, and separately in the Keychain behind Touch ID. Changing the PIN re-wraps one small key, so it is instant rather than a re-encryption of everything.
- Unlocked, the key exists only in memory. It is discarded on lock, on a timeout you choose, and on sleep. Decrypted scratch copies go at the same moment.
- Five wrong guesses start an escalating cooldown that survives a relaunch, on every path that takes a guess β unlocking and changing it both.
Four digits, and still no offline attack. 10,000 combinations is fine against someone typing into the app, because the cooldown stops them. It would not be fine against someone with a copy of vault.wrap β a backup, a cloned disk β who could guess against the file as fast as their hardware allows. So the PIN's key is also bound to a random secret kept in this device's Keychain as ThisDeviceOnly: it is in no backup that restores elsewhere and never syncs. Without it the file is worthless, whatever PIN is tried. Moving to a new Mac therefore means setting the PIN again; the master key comes along through iCloud Keychain, so sealed items open as before.
Titles stay visible; contents do not. A locked item is still findable by name and tag, but matches nothing in its body, its file, or its OCR'd text β that last one is what stops a locked passport scan being found by searching its own contents. Sensitive content is never handed to the language model either, local though it is.
Images are OCR'd with Vision and PDFs are read with PDFKit, so their contents are searchable β that is how "discovery call" finds a phrase buried on page four of a PDF. Apple's on-device model suggests a title, tags and a one-line summary when you import something, and rewrites a snippet in a different register.
If Apple Intelligence is off, unavailable, or still downloading, every one of those falls back to plain heuristics and the app carries on. Settings shows the real status rather than pretending.
Both appearances are tuned separately, and every text tier is asserted by a test to clear WCAG AA contrast against its background β because the first monochrome palette looked perfectly fine on screen while sitting at 2.65:1.
Every binding lives in one place, PanelKeyMap, and every one is asserted by a test. The panel once drew β1ββ9 on each row with no handler behind them, which is precisely what that arrangement exists to prevent.
Global β anywhere in macOS
| Key | Does |
|---|---|
β₯Space |
Summon the panel |
β₯β§S |
Save the current selection without leaving the app you are in |
In the panel
| Key | Does |
|---|---|
β© |
Paste into the app you were just in |
ββ© |
Copy instead |
β₯β© |
Open the file |
β§β© |
Paste as plain text |
β1ββ9 |
Jump straight to a result |
β β |
Move β β β by eight, ββ ββ or β β to the ends |
βK |
Actions for the selected item |
βP βR ββ« |
Pin Β· reveal in Finder Β· delete, with a confirmation |
β₯ |
Narrow to the folder the selected item lives in |
β« |
Leave that folder again, when nothing is typed |
β |
Back exactly one level: menu β mode β query β folder β closed |
Hold β, β₯ or β§ and the footer relabels itself to say what β© will do right now, so the shortcuts are learned by using them rather than by reading this table.
In the library window
| Key | Does |
|---|---|
βL β, βQ |
Open the library Β· Settings Β· Quit |
βN β§βN βO |
New snippet Β· new folder Β· import files |
βP ββ« β§βL |
Pin Β· delete Β· lock or unlock sensitive items |
β β β β |
Move through the list or the grid |
The panel deliberately does not claim βC, βV, βA or βZ β those belong to the search field, and the tests assert the fall-through as well as the bindings, because a key map that grabs everything breaks text editing in a way no positive test would catch. One casualty: ββ« means Delete here, so the field loses delete-to-start-of-line.
git clone https://github.com/heindewilde/summon
cd summon
Scripts/create-signing-identity.sh # once β see Permissions, below
Scripts/build-app.sh # release build β dist/Summon.app
open dist/Summon.appRequires macOS 26 and Xcode 26 (Swift 6.1+). There are no dependencies β the entire app builds from the system SDK.
Scripts/run.sh # debug build, then launch
Scripts/run.sh --demo # β¦against a throwaway library
Scripts/selftest.sh # 90 runtime checks on a fresh demo library
swift test # 284 tests over the logic layer
swift test -c release # the same, in an optimised build
Scripts/perf.sh # the wall-clock budgets, on a quiet machineSUMMON_DEMO=1 points the app at a separate library (Summon-Demo), so you can experiment without touching your real one.
Coming soon. A notarised build will land at summon.technology once Summon has an Apple Developer ID. Until then, building takes two minutes and the three commands above.
Summon asks for as little as it can, and every request has a fallback.
| Permission | What for | If you say no |
|---|---|---|
| Accessibility | Pressing βV for you after you choose something | Summon copies instead and shows "press βV". One extra keystroke, nothing else changes |
| Apple Events (Finder) | Reading your Finder selection for β₯β§S | Summon copies the selection and restores your clipboard afterwards |
Global shortcuts need no permission at all β they use Carbon's RegisterEventHotKey rather than an event tap, specifically so β₯Space works the moment you launch the app.
Scripts/create-signing-identity.sh creates a self-signed certificate in your login keychain, and the build script uses it when present. This is not ceremony. macOS binds permissions like Accessibility to an app's code signature, and an ad-hoc signature is just a hash of the binary β so every rebuild looks like a different app and silently loses the grant you gave it. With a stable certificate you grant it once.
The certificate is local only. No other Mac trusts it, and deleting it from Keychain Access reverts the build to ad-hoc signing with a warning.
~/Library/Application Support/Summon/
βββ Library.store SwiftData β titles, tags, folders, plaintext bodies
βββ Blobs/ managed copies of imported files
βββ Vault/ AES-GCM sealed blobs
βββ Thumbnails/
βββ vault.wrap the wrapped master key, its salt, kind, and lockout state
Files you add are copied into Blobs/ rather than referenced, so moving or deleting the original never breaks an item β and content hashing means adding the same file twice dedupes instead of piling up.
Backing up is copying that folder. It is self-contained, and sensitive items stay encrypted inside it. Time Machine already covers it.
Stated plainly, because an app that asks for Accessibility and holds your bank details ought to be the kind that tells you what does not work.
Auto-paste needs Accessibility. It is used for exactly one thing: pressing βV for you. Decline it and everything else still works.
Launch it with open, not by running the binary directly. macOS attributes a permission to the responsible process, so a binary exec'd from a terminal inherits the terminal and reports Accessibility as denied even when the grant is in place.
Touch ID unlock is unavailable in a locally-signed build. A key guarded by SecAccessControl lives in the data-protection keychain, which requires a keychain-access-groups entitlement prefixed with an Apple Team ID. A local build has no team, and adding the entitlement unprefixed makes the app fail to launch outright. Summon probes for this at runtime and hides the option rather than offering something that throws. PIN unlock is unaffected β the master key is wrapped twice, independently, for exactly this reason. (Nor can such a build bind the PIN to the device, so there the PIN wraps the key on its own.)
Apple Intelligence is optional. Every feature that uses it falls back to deterministic heuristics when it is off, ineligible, or still downloading.
Two devices means two unlock budgets. The wrapped key and the count of wrong guesses are device-local β syncing the count down would clear a cooldown someone else is serving, and syncing it up would lock you out of a device you are holding. So each device throttles its own attacker, and each has its own PIN.
Sealing cannot reach back in time. Marking an item sensitive protects it from then on; a copy that already synced as plain text is already on Apple's servers, and no local scrub reaches it. Summon says so at the moment you seal.
The keyboard extension is not in v1. A keyboard that could reach your library needs Full Access, and one that works without it cannot. Widgets, Shortcuts and the share sheet cover the same ground without the trust ask.
OCR covers English and Dutch. Hard-coded, and easy to extend.
Summon is sandboxed, as the App Store requires. Reading the Finder selection over Apple Events needed a temporary exception the Store rejects, so files arrive the other way round: Finder hands them over through Quick Actions β Add to Summon, the Services menu, or a drag. Pasting into another app still works β that is the Accessibility permission, which the sandbox does not mediate.
Sources/
SummonKit/ Pure logic. No views. The entire test surface.
Model/ SwiftData models, LibraryStore, folder icons, starter library
Vault/ AES-GCM sealing, device-bound PIN wrapping, Touch ID, lock lifecycle
Storage/ Managed blob store, content hashing, scratch materialisation
Search/ Fuzzy scorer, frecency, app affinity, query parser, index cache
Keyboard/ PanelKeyMap β every binding, as pure data
Intelligence/ Heuristics, Vision and PDF extraction, on-device model
Capture/ Clipboard monitor, selection capture, importer
Insertion/ Pasteboard writing, focus restore, synthetic paste
HotKeys/ Carbon RegisterEventHotKey wrapper
Support/ Library paths, logging, RTF
SummonUI/ SwiftUI views, design tokens, AppModel
Summon/ Executable: scenes, panel window, menu bar, test harnesses
SwiftData models are main-actor bound and not Sendable, so ranking works over ItemSnapshot value types instead. That keeps concurrency simple and makes the whole search layer testable without a store.
The schema followed CloudKit's rules from day one β no unique constraints, every relationship optional with an inverse, every attribute defaulted β which is why turning sync on was a change to one line rather than a migration. Usage history and payloads too large for a phone live in a second, device-local store: "does not sync" is a property of a store in Core Data, not of a record.
The panel and the library draw the same row. Three surfaces had grown three heights and three type scales before they were collapsed into one component; density cannot drift between them now.
| Language | Swift 6.1, strict concurrency |
| UI | SwiftUI, with AppKit where SwiftUI cannot reach β a non-activating NSPanel, an NSTextField search field so the arrow keys can drive the list, NSTextView for rich text |
| Data | SwiftData over SQLite |
| Crypto | CryptoKit (AES-GCM, HKDF), CommonCrypto (PBKDF2), Security, LocalAuthentication |
| Intelligence | Vision, PDFKit, FoundationModels |
| Shortcuts | Carbon RegisterEventHotKey β no permission required |
| Dependencies | None |
| 284 tests across 50 suites | The whole logic layer: vault round-trips and wrong-secret rejection, the cooldown holding against a clock set backwards, that extraction opens no socket and that a seal leaves no plaintext in the store file, ranking and frecency, folder trees and cycle refusal, every keyboard binding and the keys the panel deliberately declines, contrast ratios, and content edge cases from empty titles to right-to-left text |
| 90 runtime checks | Scripts/selftest.sh drives the real app: hot key registration, panel window configuration, search reaching inside a PDF, the vault lifecycle end to end, and each keyboard binding actually reaching behaviour |
| Performance budgets | Structural ones β "typing never rebuilds the index" β run everywhere and fail the build. The wall-clock ones run only in Scripts/perf.sh, which refuses outright if the machine is busy, because a budget measured beside a running test suite or a busy editor measures the scheduler rather than the code |
| A paste round trip | Opens a scratch document in TextEdit, summons a snippet into it, and reads the result back through the Accessibility API β refusing to run unless TextEdit is genuinely frontmost |
| Budget | Measured | Limit |
|---|---|---|
| Keystroke β results, 2,000 items | 0.55 ms | 4 ms |
| Empty query β runs on every panel open | 0.31 ms | 4 ms |
| Index build, 2,000 items | 13.5 ms | 25 ms |
| Typing rebuilds the index | never | asserted structurally |
Budgets assert on the fastest of many runs, not the mean or the worst. Timing noise is one-sided β the scheduler only ever adds time β so the minimum is the honest estimator of what the code can do, and asserting the maximum produces a flaky suite whose usual fix is raising the budget until it means nothing.
That estimator has a limit worth naming: it assumes some sample lands in a quiet slot. Under sustained load none does, and the floor itself moves β the index build reads 13.5 ms on an idle machine and 37 ms at load 24. So the wall-clock budgets do not run in the ordinary suite at all, and Scripts/perf.sh checks the load average and refuses rather than printing a number that is about the machine.
- The App Store, both apps β one purchase covering Mac, iPhone and iPad; free
- A keyboard extension β cut from v1 over Full Access; Shortcuts and widgets cover most of it
- Rich-text editing everywhere β done on both platforms; lists and links still want work
- Keyword expansion β type
;siganywhere and have it expand in place - Smart collections β saved searches that behave like folders
Issues and pull requests are welcome.
swift test # start here β it is fast
swift test -c release # the same, optimised
Scripts/perf.sh # the wall-clock budgets, if the machine is quiet
Scripts/selftest.sh # drives the real app end to endTwo things worth knowing before digging in:
SummonKithas no UI imports. If logic can live there, it should β that is what keeps it testable without launching an app.- Test harnesses never reach outside the app.
AppModel.isHarnessmakes delivery record what would have been pasted rather than writing your clipboard or synthesising a βV. This is not theoretical: the self-test once pasted into someone's email, repeatedly, and the guard now defaults on for anySUMMON_*variable so a new harness cannot forget.
Does anything leave my Mac? Only into your own iCloud, and only if you use Summon on more than one device. There is no account, no analytics, no crash reporting, and no server of ours β sync is performed by the system into your private CloudKit database. Items you mark sensitive are encrypted before they leave; "Encrypt everything" does the same for all of them.
Do I have to grant Accessibility? No. Without it Summon copies and tells you to press βV. The global shortcut works either way.
What happens if I forget my PIN? The encrypted contents are unrecoverable β that is what encryption means. Titles, tags and folders stay readable, so you will still see what you have lost.
Do I need Apple Intelligence? No. It improves suggested titles and tags when available and falls back to plain rules when it is not.
Is it sandboxed? Yes, as the App Store requires. Pasting into another app survives the sandbox β that is the Accessibility permission, which the sandbox does not mediate. Reading the Finder selection over Apple Events did not, so files now arrive through Quick Actions, the Services menu, or a drag.
Can I use a different shortcut? Yes, both are rebindable in Settings. If another app already owns your choice, Summon tells you rather than failing quietly.
Why AGPL for a desktop app? Consistency with the rest of this profile. Its distinguishing network clause has no practical effect on an app that never serves anyone over a network.
Shaped by the tools that got the shape right first β Raycast for what a launcher should feel like, Alfred for proving the idea, and Maccy for showing how small a clipboard manager can be.
AGPL-3.0 Β© Hein de Wilde





