Format Packs
Format Packs are small WebAssembly converters that add new conversions to the shortcuts, the app and every Finder menu at once. They run in a sandbox with no way out.
Klippster ships with eight formats. A Format Pack adds more, without an app update and without any part of Klippster having to trust the pack's code.
Packs are available on the free tier. Browse and install them from Settings → Format Packs.
#What a pack can be
| Kind | What it does |
|---|---|
| PDF theme pack | Ships a pandoc or LaTeX template that renders Markdown → PDF in your own house style. Unlimited layout control. |
| New converter | Any input to any output, defined by a manifest and a .wasm module. Text, data, whatever you can compile. |
A pack's conversions appear everywhere the built-in ones do — in the ⌘⇧V menu, in Copy to Clipboard as, in Convert to, and in the Clipboard History inspector. There is no separate "packs" menu to remember.
#The sandbox
This is the part that decides whether installing a community converter is a reasonable thing to do, so it is worth stating precisely.
Packs run in a pure-Swift WebAssembly interpreter with no host imports at all. Not a restricted set of imports — none. A pack cannot open a socket, cannot read a file, and cannot see anything except the bytes you handed it to convert.
| Boundary | Enforcement |
|---|---|
| Network | No host import exists. There is nothing to call. |
| Filesystem | Same — a pack receives input bytes and returns output bytes. |
| Memory | Capped. A pack that allocates past the ceiling is stopped. |
| Output size | Capped, so a converter cannot fill your disk. |
| Wall-clock time | Capped, so a pack that loops forever is killed rather than hanging the app. |
| The Finder extension | Never executes pack code at all. |
That last row matters more than it looks. The Finder Sync extension is the component with the broadest reach into your files, so it is deliberately not the one that runs untrusted code.
#The registry
Packs come from a public registry on GitHub, and the trust chain is checked before anything is executed.
The index is signed
The registry index carries an Ed25519 signature, verified against a public key compiled into the app. A tampered or substituted index fails before any file is downloaded.
Every file is checksummed
Each pack file is checked against the SHA-256 recorded in the verified index. A file that does not match is discarded.
Only then is it installed
The pack lands in Klippster's App Group container and its conversions appear in the menus.
Because the key is compiled into the app, replacing the registry does not help an attacker — they would also need a build of Klippster that trusts a different key, which is a different problem entirely.
#What browsing a pack tells the registry
Requesting the index and downloading a pack are ordinary HTTPS requests to GitHub, so the hosting provider processes the usual connection data: IP address, timestamp and user agent. Your clipboard is not part of those requests, and a pack only ever receives the data you explicitly asked it to convert.
If you never open the Format Packs screen, Klippster never contacts the registry.
#Writing one
A pack is a manifest plus a .wasm module. The manifest declares which input types the
pack accepts and which outputs it produces; the module exports the conversion entry point. The
specification lives with the app source and will be linked here once that repository is public.
#Removing a pack
Uninstall it from Settings → Format Packs, and its conversions disappear from every menu. Deleting Klippster's App Group container removes all installed packs at once — see Install for what else lives there.