"Checking for updates..." when you are already on the latest version.
survives a restart instead of silently reverting to hourly.
This is a macOS-only test update. Windows and Linux stay on the previous complete release until the next full cross-platform build.
button while the transfer is still running, so a file cannot be sent twice by accident. Lists that refresh on a timer keep keyboard focus when nothing changed.
reachable with Tab, activated with Enter, with a visible focus ring.
dialogs: focus moves into them on open and returns on close, and Escape closes the ones that have a neutral close. Escape never accepts or declines someone else's file offer.
with autocomplete and spellcheck set so password managers behave. The tab bar, dialogs, and lists expose proper roles.
contacts) keep keyboard focus, text selection, and open previews when nothing changed. Transfer progress updates in place, and the transfer list shows the latest 200 rows.
expands. Tab stays inside an open dialog.
nearby device ask for confirmation first; approval shows the device ID to check against the other machine.
the server are length-capped and stripped of control characters before they are shown.
inline. Relative times and sizes follow the system locale.
instead of pushing numbers off the row.
History tab. The three add-device buttons have distinct labels.
This is a macOS-only test update. Windows and Linux stay on the previous complete release until the next full cross-platform build.
service, clipboard access, secure key storage, configured storage, LAN discovery, nearby devices, and automatic updates. Each problem includes a suggested next action instead of exposing an internal error.
report. The report is built from a fixed allowlist and cannot contain clips, filenames, paths, device names or IDs, email or IP addresses, URLs, logs, keys, passwords, or tokens. A file containing the same report can be saved for manual attachment; screenshots are never captured automatically and carry a privacy warning.
and descriptions use shorter language, Folder Jobs is now Folder sync, and the tray menu has a direct Troubleshoot ClipNSync route.
syncing now also polls configured folder or WebDAV storage immediately, rather than nudging only the LAN mesh.
This is a macOS-only test update. Windows and Linux stay on the previous complete release until the next full cross-platform build.
devices, sync and storage, history and privacy, file transfers, security and recovery, account, advanced controls, and reset. Repeated controls and conflicting descriptions are removed.
when this computer will leave the mesh, clears only ClipNSync-owned local data, preserves shared cloud/NAS storage, and returns directly to first-time setup.
folder is selected. The app-managed LAN folder is identified clearly, while cloud, WebDAV, NAS, and other shared locations are never erased by a device reset.
a clear route back instead of leaving someone trapped without an understandable next action.
network discovery guidance, and waiting-device protection as desktop. Recovery also restores legitimate device membership using the same proof-gated self-heal used at startup.
connect this computer. Both choices use the same visual weight, LAN is recommended, and shared/cloud folders stay available without getting in the way of the common local-network setup.
another computer that is also waiting for first-time setup. An established mesh suggests connecting; two fresh computers explain that one must finish setup first. The new waiting announcement carries no clips, keys, device name, vault information or protocol change, so older versions ignore it and configured systems are unaffected.
pairing kept as alternatives. Completion text also reflects what actually happened instead of claiming that a first device connected to another one.
and dynamic mesh wording. It disconnects this computer when necessary, clears ClipNSync's local state, and returns to first-time setup. It does not delete the selected shared/cloud/NAS folder or data belonging to other mesh members.
asks for broad storage access during an ordinary LAN setup, and mobile pairing presents camera QR scanning and the manual code as explicit alternatives.
then the device still sat there not syncing until you found the Trust button and pressed it on BOTH machines -- and if you did not know to, you had a paired device that never worked. The cause was two unrelated identities: the keypair pairing exchanges, and a separate mesh id that is four random bytes. Nothing connected them, so pairing could not mark the device trusted even in principle. The mesh id now travels inside the authenticated pairing exchange and both sides trust each other the moment pairing succeeds.
leaving you on the same instructions unsure whether it worked.
were never your own machine and never duplicates: the list synthesises a row for each trusted device that is currently away, and those rows carried an id but no name, so an empty name rendered as "This device". Two sleeping devices produced two identical rows.
screen. A crafted name could reverse text or add what looked like an extra line of the app's own wording; names are now cleaned before they are stored, not just before they are shown.
Devices on an older version pair exactly as before, without the automatic trust -- verified by running the new build against the previous one over a real connection, in both directions. iPhone, iPad and Vision Pro deliberately stay on the older pairing protocol for now; they pair as they always have.
could sit on "Still looking" forever while the other Mac was plainly there, which also meant the code never appeared -- the code is shown only after you pick the waiting device from the list, so a list that never fills is a flow that never starts.
instead of once a day. A fresh install defaulted to daily, so a device sitting on the setup screen -- exactly when a fix matters most -- went quiet for 24 hours and had to be reinstalled by hand.
match the desktop: they say the code is 8 digits, group it as you type, and open a keyboard that leads with numbers. They still accept the letters-and-digits code that devices on older versions show.
Settings and it is open, and there is a button at the top of the Clipboard tab that goes straight there. It used to be fourth of eight sections AND collapsed, so following the setup instructions to the letter did not reveal it -- the instructions themselves also skipped the step that was hiding it, and now name the shorter path.
running, a device waiting to join raises a notification and a banner offering to open the right screen with that device already picked, so you no longer have to go looking for it. Seeing that announcement grants nothing on its own: the code exchange still decides everything, and there is no way to approve a device without it.
Mixed characters were the actual typing pain -- case, and O against 0, and I against 1 -- and the field now formats itself as you type. Devices still running an older version show the old letters-and-digits code, and this version accepts those unchanged, so a new device can still join from one that has not updated yet.
Security note on that last one. The code is a password inside a SPAKE2 exchange, not a value to compare, and a wrong code burns after five attempts against the code itself across any number of connections, with the code expiring after three minutes regardless. Eight digits therefore leaves an attacker 5 chances in 100,000,000. That is a smaller margin than the previous code carried, and it is a backstop rather than the defence -- the attempt limit is what actually stops guessing. The direction is unchanged and deliberate: the device that already holds your key shows the code, and the new device's owner types it, because the new device is the one adopting a key and so is the one that has to be convinced.
network. There was a 50 MB limit, and it was the wrong way round: a file too big to send directly would still sync through your cloud folder, so the fastest route was the only one that refused. Neither device holds the file in memory now, so a multi-gigabyte transfer costs about as much memory as a small one.
ClipNSync was encrypting in software on Apple Silicon and most Android phones instead of using the encryption built into the chip. Nothing about the encryption itself changed; it is simply done the fast way now.
rather than through your router, with no internet and no account needed. It falls back quietly when it cannot.
working at all, which looked exactly like the app had frozen.
decrypted into your download folder once you accept it. Declining leaves nothing behind, and a transfer interrupted halfway cannot leave a partly written file that looks complete.
on your network, and offers to join rather than start again. It stays quiet when it finds nothing, because not finding a device is not the same as there being none.
pasted.** Your clips were always encrypted and that never changed -- nobody could read anything they were not meant to. But a device that could WRITE to the folder could take a clip you had already received and offer it again under a new name with a later time, and ClipNSync would treat it as the newest thing you copied and put it on your clipboard. No key was needed, because nothing was forged: it was your own clip, replayed at a moment of someone else's choosing. The risk is what you would paste next -- an old payment address before a transfer, a stale password at a login. Every version up to and including v0.21.18 is affected, and anything able to write to the folder could do it, including a device you had already removed. It is fixed on every path that reads a clip, and any such clip already in your history is removed when you update.
stopped it receiving anything new but left it holding the old key -- and removing a device here does not remove that machine's iCloud or Dropbox account, so it could still read everything already in the folder. Removal now re-encrypts what is stored, leaving the removed device with files it cannot open. It cannot recover anything it copied before you removed it; nothing can.
iPhone, iPad and Vision Pro the vault key sits behind the Secure Enclave, and Face ID is genuinely required to reveal your passphrase rather than merely being asked for. On Android ClipNSync now requests a secure element and reports which protection it actually got.
outside the folder it belonged in** if the sending device chose a crafted name. Only a device you had already paired could do it, but a paired device could do more than send you a file. Fixed.
first phone's identity.** It used to, and two devices sharing one identity quietly overwrote each other's record of what they had seen, which showed up as clips going missing at random. Restoring a backup now asks for your passphrase again.
-- which could happen when two devices updated at the same moment -- it puts itself back with nothing shown and nothing to do. A device you genuinely removed cannot, and is told what to do instead.
one has been possible for a while; using it was not.
longer readable by other accounts on the same computer, and deleting a clip really erases it.
recovery phrase before you need it rather than after.
security problems in the software ClipNSync is built on.
shows an 8-character code; you type it on the new device and they are paired. There is no longer a code to compare on two screens, and nothing to confirm twice.
the screen tells you how many tries are left. After five wrong tries it stops working and you start again for a fresh one.
other device was still being added could let the pairing finish anyway, silently, while the screen said nothing had been sent.
network. It is used to authenticate the exchange itself, so a device that was not told the code cannot join -- and cannot work the code out by guessing offline either. Your encryption key still never leaves your devices.
and they ship inside the app.
once, left version numbers and folder paths blank, and did not respond to any button. Nothing was wrong with your setup, your clips or your pairing -- syncing kept working the whole time, only the window was broken. If you are on v0.21.16, updating to this version restores it; nothing needs to be re-paired or set up again.
code that happened to contain the characters that end a web page's script section, which silently discarded everything after it. A new release check now loads the window in a browser and refuses to publish unless it draws exactly one screen and fills in its values, so a window that does not work can no longer reach anyone.
record of everything you have copied rather than just the last hundred items. Text is small, so this costs very little disk. Images and file clips still expire on their own timer, which is where the disk actually goes, and you can set text to expire after 30, 90, 120 or 365 days instead if you would rather it did not accumulate.
line. Previously only the first 80 characters were searchable, so a long query, a log excerpt or a block of config was saved perfectly and then could not be found by anything further in. It also searches the older clips that are no longer held in memory, so something copied months ago is still reachable by typing a fragment you remember. Matches are highlighted, and the list loads more as you scroll.
typing anywhere on the Clipboard tab to search, use the up and down arrows to pick a clip, press Enter to copy it back, and Escape to clear the search.
short time instead of always being ignored. The default is unchanged and still ignores them completely; if you turn it on you choose whether they stay on this device only or sync like any other clip, and how many minutes they live for. Expiry runs while the app runs, so a device that was asleep clears them on waking rather than exactly on time.
devices. One computer can keep its history forever while another clears it after a month, and neither removes the other's copy.
no longer loads every stored clip at startup, reading each one only when it is actually needed.
it can be read, and the app's log file no longer grows past its size limit while the app keeps running.
window gone, and reopening it put a default-sized window in the middle of the screen, wherever you had actually placed and sized it. It now comes back with the same position, the same size, maximized if it was maximized, and on the tab you were using. A window that was minimized or closed before the update stays that way rather than being pushed in front of you.
restored off into nothing. If the saved position does not land on any connected display -- an external monitor unplugged, a laptop reopened somewhere else -- the window is centred on your main screen instead, keeping its size where that still fits. A window deliberately hanging off the edge of a screen is left exactly as you put it.
longer wakes to a red warning about a clipboard that is now perfectly free. A clip that arrives while another app holds the clipboard is parked and retried for up to a minute before you are told anything. Sleeping spent that whole minute without a single retry being attempted, so the first moment after waking -- which is exactly when the clipboard is busiest, with the session restoring and clipboard managers starting up -- produced an immediate failure notice with no grace left at all. The app now notices that it was suspended and recovers instead: the parked clip is dropped rather than reported (an hours-old clip should not land on the clipboard you are about to use, and it is still in your history to click), any leftover warning is cleared, the sync folder is checked straight away rather than after the usual wait, and devices on your local network are nudged to sync immediately. Waking is treated as a fresh start rather than the continuation of a problem from the night before.
app cleared these as soon as the next clip or folder check succeeded, but the window kept displaying the old message until some unrelated click happened to replace it, so a moment of trouble could look permanent. Messages you get from pressing a button are untouched and still stay put until you act.
clipboard is no longer lost, and no longer raises a red banner that stays up. The clipboard on Windows is a single global lock that remote-desktop sessions, Office and clipboard managers take for seconds at a time; previously the app blocked for about four seconds, gave up, marked the clip as already applied so it was never tried again, and left "The native clipboard is not accessible due to being held by another party" on screen until some later clip happened to succeed. The clip now keeps being retried quietly, once per sync tick, for up to a minute, and the content is only recorded as applied once it is genuinely on the clipboard. That minute is a firm ceiling: more clips arriving while the clipboard is stuck replace the one waiting, but do not restart the clock. If the minute passes, the message finally shown explains who is likely holding the clipboard and points at the history entry.
something you copied yourself in the meantime; it stays in your history to click. On Windows this covers any change by any application, checked at the moment of writing. On Linux under X11 there is no equivalent to check, so it covers only copies ClipNSync itself captured that moment; anything the capture path skips -- a sensitive or ignore-pattern copy, an image or file selection copied on an unsampled tick, a copy over the size cap -- can still be overwritten. See docs/KNOWN_LIMITATIONS.md. macOS is unaffected either way, because a clip is never set aside there.
disk. The file was written before the clipboard write was attempted, so every failed attempt left one orphan.
when only the extra "paste it as a file" convenience failed. The image pastes; there is nothing for the user to act on.
A device worked out what its peer was missing from the peer's contiguous progress marker alone, and that marker can only advance over an unbroken run of clips. One permanently unreachable early clip -- dropped by the history limit, or created before the other device was ever paired -- pinned the marker in place for good, so every few seconds each device concluded the other was missing its entire history and sent all of it again. The receiver stored it all, changed nothing, and the cycle repeated indefinitely. Devices now also account for the clips a peer has already taken out of order, which is what lets the exchange finish. This was costing bandwidth, CPU and battery on both machines; no clip was ever lost or duplicated by it.
on arrival the same way its other progress fields already were.
The device tiles read the device id under the wrong name, so each tile carried the literal text "undefined" and the send was aimed at a device that cannot exist. It came back as "that device is no longer linked to your account", which sent people looking for a broken account or pairing when nothing was wrong with either. Sending to a contact, or by email address, was never affected. A tile that somehow has no device id now falls back to the all-devices send that works, rather than failing every time.
displaying the word "null" in red. Failure text lives only in memory today, so restarting the app still loses the detail of an older failure.
The guard is an operating-system lock taken in the first moments of startup, before any files, settings or stored credentials are touched, and a launch that loses it hands its command line to the running copy and stops. Previously the check ran several steps into startup and, if it could not reach the running copy, allowed a second one to start anyway -- two apps then shared one clip database and one sync folder. Different users signed in to the same machine each still get their own copy.
line in a narrow window instead of running off the edge, long file names and addresses wrap or ellipsize, and drop-downs and text fields shrink to fit rather than forcing the page wider than the window.
launches on a device that is already set up (a vault exists for the configured sync target), it registers itself with the operating system's per-user login items -- no admin rights, same mechanism the Settings toggle has always used. This happens exactly once per install: turning "Start at login" off in Settings is permanent, and the automatic default never applies again on that device. Devices that have never completed setup are left alone until they have.
Capturing previously rewrote and flushed the complete encrypted local store twice, then waited for the folder/WebDAV backend and history database before starting the network send. A capture now makes one atomic local commit, immediately queues the authenticated LAN delivery, and moves slower indexing and backend persistence off the critical path.
networks. Bonjour/mDNS routes are filtered to match the listener, the last authenticated address is tried first, failed directions time out quickly and back off, and a lightweight one-second reverse-path sync lets a reachable device return missing clips on the connection its peer opened. The encrypted folder/WebDAV backend remains the durable fallback.
Activating an image publishes both its bitmap and a temporary private PNG-file representation, so image editors still receive pixels while file managers receive a real file.
nothing when pasted. Windows file-list clipboard writes now retry global clipboard contention and verify the complete file list. The UI waits for the operating system to accept the item before reporting success, on all desktop platforms.
single-commit durability, route selection, firewall backoff, discovery filtering, and image materialization.
real dimensions instead of "[image/png - 707205 bytes]". A single click opens a preview; a double click copies. Image syncing already worked, but there was no way to tell a working copy from a failed one, and pasting into a text-only field silently did nothing.
paste real files on another desktop. The bytes travel with the clip, so deleting the original on the sending machine does not matter. Files above 25 MB ask before sending; very large files are pointed at File Send, which is built for them.
a firewall stopped one device being reached, its clips never left it, even though it received everything fine. Devices now send clips back over the connection the other device opened. Both devices need to be on v0.21.8 for this; a device still on an older version keeps working exactly as before.
budget (default 2 GB) and how long to keep clips (default 30 days). Pinned clips are never removed by either limit. Clip history previously had only a count limit, which is not a real limit on disk once images and files are involved.
another app; a decrypted filename leaking into the local log was fixed; a PNG with absurd declared dimensions is now rejected before it can exhaust memory.
Upgrade path: v0.21.5 -> v0.21.7. There is no v0.21.6 build to install. v0.21.6 was tagged, but its release workflow never produced any installers (the CI budget ran out mid-release), so no v0.21.6 artifact was ever published and nobody is running it. Everything listed under v0.21.6 below therefore reaches users for the first time in this release -- most importantly the fix that lets a device rebuild its own vault file and keep pairing working.
earlier attempt had been abandoned part-way through. The half-finished attempt left a stale vault file behind, and the next attempt refused to replace it, so pairing kept failing until the app was reset. Completing the pairing now replaces that leftover file, because a pairing you confirmed on both screens should always win over an abandoned one.
app was fully restarted, which meant re-running setup to get syncing again. The setup now survives a restart.
Both fixes are in the Apple apps and the shared core. Desktop behavior is unchanged from v0.21.6.
Technical changes (no user-visible effect):
MobileSession::create_new_vault, a v2 constructor removed as dead FFI surface, so cargo test -p clipnsync-core --features mobile did not compile. They now use the same create_new_vault_for_test scaffolding the rest of the suite already used. The library itself always built, so no shipped behavior was affected; only the test target was broken, and CI does not exercise that feature, which is why it went unnoticed.
Development infrastructure (maintenance, not shipped in the app):
exhausted and blocked releases for several days -- the direct cause of v0.21.6 never shipping. Push and pull-request CI now builds Linux x64 and Windows only; macOS (billed at 10x) and ARM Linux moved to an on-demand switch. Tagged releases are unchanged and still build all four platforms, so release artifacts are identical in scope.
to completion, and documentation-only changes no longer trigger a desktop compile.
device, failing with "No vault exists here yet". This happened when the small vault file went missing or was corrupted (for example after a cloud-folder problem or switching sync methods). The app now rebuilds that file automatically from the key it already holds -- on startup and when you add a device -- so pairing works again with no reset and nothing lost.
fail instantly -- the verify-code screen flashed and disappeared -- even when the devices were on the same network and file send between them worked. When a device advertises several network addresses, pairing now tries all of them (the same way file send already does) instead of giving up on the first unreachable one. Adding phones, tablets, and computers over the LAN is reliable again.
like iCloud/Nextcloud to "This network only (LAN)") left the new location without your vault. Clips still synced, but adding a new device over the LAN failed with "No vault exists here yet", because pairing needs the vault in the active sync location. Your vault now follows the switch automatically, so LAN-only is fully self-contained and device pairing works after changing sync methods.
source repository. If you already have the app installed, download this version once from https://clipnsync.com/ -- from then on it updates itself from the website automatically.
to set up, it just works as soon as two of your devices are on the same network. (Existing installs keep whatever sync method you already chose.)
The v0.21.1 fix was incomplete. A stack trace of a frozen app showed the true cause: when a clip file in your cloud sync folder could not be read (for example an expired Nextcloud login left the file un-downloadable), the read would hang, and it was holding the internal lock that the rest of the app needs -- so the whole window stopped responding until the app was killed.
no longer freeze the window: the clipboard status, file-receive check, and device-status view now skip a busy moment and try again next tick instead of waiting on that lock. The app stays responsive; sync resumes on its own once the folder is readable again (for example after you re-sign-in to your cloud app).
Urgent fix for a v0.21.0 bug that could freeze the whole app.
read was slow or a device connection could not complete -- a background check was running on the main window thread and getting stuck. That check now runs off the main thread, so a slow sync or a stuck connection can never freeze the window again.
seconds instead of hanging, so an unreachable device (for example on a Wi-Fi that blocks device-to-device connections) fails with a clear message instead of appearing frozen.
login (Nextcloud, iCloud, OneDrive) now reads "your cloud app's sign-in has expired -- sign in again" instead of a raw "io error ... (os error 81)".
account and no cloud service needed. It goes directly over your local network when both devices are on the same Wi-Fi, and falls back to your shared folder when they are not. The receiving device always asks before saving, and now shows which device the file is coming from so you know who sent it.
of stalling.
the confirmation button ("They match - Add") scrolled off the bottom with no way to reach it, so pairing never finished. The dialog now scrolls, and the local-network method (no camera, no QR scan, no shared folder) is shown first as the simplest way to add a device.
reappear on a device after a restart. Plus internal cleanup of an old unused vault-setup code path.
Polish for local-network pairing based on real-device testing.
ONCE under "Nearby devices asking to join", instead of showing up twice.
devices that all report a generic name (for example iOS shows every iPhone as just "iPhone") can be told apart and matched to the one you are adding.
this computer's QR / typing its code (which uses your shared sync folder) versus adding a device over the local network (which needs no folder), and the "type a device's code" option is easier to find.
You can now add a device purely over your local network, without both devices sharing a cloud folder. This makes a mixed setup work: keep an iPhone on your local network only while your Mac and PC sync through Nextcloud (or any cloud folder), and they still share one clipboard.
you already set up, open "Add a device" and pick it under "Nearby devices asking to join".
"They match" on both. That is all: no long code to type, no camera needed.
directly to each other, and your encryption key is delivered so that only your two real devices can read it -- never anything else on the network.
Each device now has its own key. Adding a device is a QR scan: the new device shows a QR code (and a short backup code), a device you already set up scans it, and they connect -- no long passphrase to type across devices, and no shared secret ever travels or touches the cloud in the clear.
must be set up once more. Set up one device, then use "Add a device" to scan each other device in. This is the only time you will need to do this.
(for example your iPhone's name or your computer's hostname), so you no longer see phantom duplicate devices.
your clips even if you lose every device.
(no nested "clipnsync" wrapper).
A batch of improvements. No re-setup required.
-- and when it was last seen.
the shared folder), and a deleted clip stays deleted (no resurrection).
"Sync now" -- it is now just a manual override.
Desktop now participates in the same version-vector sync recovery that shipped for iPhone/iPad/Vision in v0.18.0: a desktop on your local network can recover clips a peer copied while it was away (beyond the small recent window) directly over the network, and serve the same to other devices -- not only through the shared cloud folder. Cloud-folder sync is unchanged. No re-setup required.
Makes clipboard sync resilient across a mix of cloud folder and local network, so a clip you copy on one device reliably reaches the others and missing clips are caught up automatically when a device reconnects.
record of what every other device has produced and what it has replicated. Devices exchange these records and fetch exactly the clips they are missing -- no longer limited to a small recent window, so a clip that was copied while a device was away is still recovered later.
folder and your local network automatically bridges clips between them, so a device that only syncs over Wi-Fi and a device that only syncs via the cloud folder still converge.
missed, instead of waiting for the next periodic sync.
Under the hood this uses an authenticated, version-vector anti-entropy protocol; the cloud and network only ever see encrypted clips and public sequence numbers, never your data. The new recovery path is active on iPhone, iPad, and Vision now; desktop continues to converge through the shared folder as before, with the same local-network recovery to follow.
Makes setup and recovery simple and consistent on every platform.
"Have you already set up ClipNSync on another device?" -- no jargon.
an older version stops silently reusing its saved key and walks you through reconnecting, instead of quietly running on a setup your other devices can no longer join.
(reset just this device, leaves your others alone) and "Reset everything and start fresh" (start over on all devices). Both keep a typed confirmation, and neither ever touches the contents of your shared cloud folder.
Fixes a regression from the v0.17.0 encryption change. The new encryption also protects the local caches that File Send and the clipboard history use, and older caches written by a previous version could not be read -- which showed up as "decryption failed" when signing in to File Send, and could block the local clipboard store from opening.
version. Unreadable local caches (transfer history, resumable transfers, the local clipboard store) now reset themselves cleanly instead of blocking you. These caches hold nothing irreplaceable: history is for display, interrupted transfers simply restart, and clips re-sync.
decryption failure on current data is still rejected, never ignored.
Follow-up to v0.17.0's encryption rewrite, fixing the first-run experience.
question -- "Have you already set up ClipNSync on another device?" -- routes you to either creating your first device or adding this one to an existing setup, one step at a time. The word "vault" is gone from the screens.
still holds an older, unreadable ClipNSync setup, the app now detects it and offers to replace it with a new one (you re-add your other devices), instead of failing to parse it. A malformed or foreign vault anywhere (folder, join code, or a LAN peer) now reports a clear message rather than a technical one.
parsing, so a mismatched format fails cleanly and never leaks internal details.
IMPORTANT: this release changes the encryption and vault format for stronger, simpler multi-device security. It is a clean break: your existing vault is not migrated. On each device you set up your vault once more -- create it on your first device, then Join it on the others.
your passphrase plus a public salt that is now SHARED across your devices, so every device with the passphrase decrypts every clip -- whether the clip arrived over the local network or a cloud folder. (Previously, setting up a device on a different folder silently created a SEPARATE vault with its own salt, so two devices with the same passphrase could not sync -- the cause of "same passphrase but nothing synced.")
"Join my other devices" (add a device by scanning a QR / entering a short code from another device, or pointing at the same shared folder). Joining transfers only PUBLIC vault info (never your key); the code is useless without the passphrase.
Create while an existing vault is visible (same folder, or a device on your network), it asks "Found an existing vault -- join it instead?" first.
keys, and a passphrase check so a wrong passphrase fails fast with a clear message instead of producing unreadable data. Clips carry a device id, time, and sequence number for reliable ordering.
removed -- joining now shares only the public salt, keeping your passphrase the single secret.
TestFlight-only (desktop unchanged):
the same dark theme and accent, and the same tabs -- Clipboard, File Send, Usage, Settings, About. On iPhone the tabs are along the bottom; on iPad and Vision Pro they run across the top like the desktop.
in one place: what to capture, where received media goes, your sync folder, privacy and local-network options, your devices and pairing, passphrase recovery and reset, your account, and a full Diagnostics view.
matching the desktop, so the same read-only debug info (app/keychain/ account/LAN/sync state and a recent transfer log, never any secret) is available everywhere for troubleshooting.
a glance while testing: app version, whether the OS keychain is healthy, account link state, this device's id and file-transfer key fingerprint, the direct-LAN status (advertising, browsing, peers, last peer seen), the sync folder and backend, and a recent send/transfer log. It is read-only and never shows any secret (no passphrase, token, or full key) -- only presence indicators and public identifiers -- so it is safe to screenshot when reporting an issue. This mirrors the Diagnostics already on iPhone, iPad, and Vision Pro, so the same debug view is now available on every platform.
TestFlight-only (desktop unchanged):
cloud folder being reachable. Copies now go into a small encrypted store on the device, and same-network devices sync clipboard directly over the local network first, so a slow or unreachable cloud folder (for example Nextcloud taking its time to mount) no longer stops clipboard sync. When the cloud folder is reachable, clips are still written there so your desktops keep receiving them, and a device that synced only over the local network pushes those clips up to the cloud once it reconnects. Clips are end-to-end encrypted with your passphrase on every path, and a clip received only over the local network is now kept safely instead of being lost when the app restarts.
TestFlight-only (desktop unchanged):
shows for at most about 4 seconds, then drops to the setup screen with a Reconnect button and the option to use a folder on this device, while it keeps trying your saved folder in the background and connects on its own once the folder is reachable. Before this, a slow cloud folder (for example Nextcloud taking its time to mount right after launch) could leave you stuck on the spinner for a long time with no way out.
single "All my devices" option to send to everything at once. Sending to a device always uses the fast File Send path (the local network when the device is reachable, the internet relay otherwise) with full history and resume. Previously the same device could appear twice -- once as a local-network entry and once as an account device -- and picking the local-network one silently sent over an old channel capped at 25 MB, so a larger file (for example a big log or video) would just vanish with no history entry and no error. You no longer have to think about "local" vs "remote"; the app picks the fastest path for you.
no prompt on the other device, nothing sent, and no error shown. When you picked one of your devices as the target and the server's last "this device is online" heartbeat for it was even a moment out of date, the send was quietly parked instead of ever trying the local network or the relay. A send to your own device now always tries to deliver right away (local network first, relay as fallback) regardless of that cached status, the same way the direct local-network path already did.
directly device-to-device over the local network (fast) instead of routing through the internet relay. Previously the desktop app treated your own devices like a contact and never attempted a direct connection, so same-network transfers always went the slow way. Your own devices now always try the direct path first, with the relay as an automatic fallback; the privacy setting that asks before connecting directly to a contact is unchanged. Every direct connection is still authenticated end-to-end, so only your own devices can connect.
TestFlight-only updates on top of desktop v0.16.3 (the desktop app is unchanged):
Files" opens a location picker so you choose any destination (a folder on the device, an external drive, or iCloud), and the file is moved there rather than copied, so a very large file is not stored twice. If you cancel the picker the file is still saved into the ClipNSync folder, so it is never lost.
tells you and offers Open Settings or Save to Files instead. Before this it quietly saved to Files, which made a photo or video look like it had not saved at all.
to it ("View in Photos" or "Show in Files"); it previously could fail to appear.
folder is slow to come back (for example a cloud folder that is slow to mount), the app drops to the setup screen after a few seconds with a Reconnect button and keeps retrying in the background, so you can still pick a folder or use one on the device instead of waiting with no way out.
v0.16.3 change above): the phone now listens longer and announces itself the instant you accept, so the direct connection wins instead of falling back to the relay.
of saving silently, and are never lost -- if you close without choosing, the file is saved to Files.
actually take (photos and videos); everything else offers Files. Videos no longer fail to save with a Photos error.
time remaining.
you to pick the folder and re-enter the passphrase.
TestFlight-only updates on top of desktop v0.16.2 (the desktop app is unchanged):
your Photos library (you are asked once for permission), and every other file saves into the ClipNSync folder in the Files app. Before this, a received file could finish transferring but be left in app storage that no other app could open, so it looked like nothing arrived.
to Files, Photos, AirDrop, or another app. Received photos and videos show an "In Photos" note instead, since they are already in your library.
now arrives reliably, including over the internet (the matching Apple-app side of the desktop v0.16.2 fix below).
silently never arriving after that device had signed in more than once. Each sign-in used to leave an extra stale device registration behind on the server, and a send could be delivered to one of those dead registrations instead of the live device. Signing in now retires this device's own previous registration, and a device that has just signed in is treated as a live send target right away instead of being skipped until its first check-in.
the internet relay when a direct local connection is not available, so a file sent to your iPhone arrives even when the phone is on a different network. Previously such a send could be dropped silently if the device was not reachable on the local network at that moment.
on LAN" instead of "Sent", which had implied a delivery confirmation that path cannot give, and they can now be removed from history.
30 days), so you can see past transfers and re-send a file without hunting for it again. The history is stored encrypted on the device.
to your Photos library, everything else to Files, with a prompt before overwriting a file that already has the same name.
cancelling a transfer while it is resuming now cleans up properly.
an incoming file takes it; the prompt clears on the others by itself.
has it set up (behind Face ID / Touch ID on iPhone, a confirmation on desktop), pair a new iPhone from an existing device using a QR code plus a short code, or, as a last resort, reset to a brand-new passphrase. Reset makes clips under the old passphrase unreadable and is confirmed by typing RESET.
features (iOS build 11, visionOS build 5).
never gets its bytes (for example the sender went offline mid-send) now fails cleanly after a couple of minutes with no progress instead of showing "receiving" forever; a transfer that is slowly but steadily progressing is never interrupted.
gives up cleanly, so a pile of stuck transfers can no longer flood the server or lock you out of new sends.
and stuck transfer at once (they no longer come back on restart).
account's devices and delivers to them over the relay even when they are not on your local network. Stale/duplicate device registrations are filtered out automatically.
mobile apps use the exact same discovery/trust/transfer code. No change to how the desktop behaves on your network.
devices" entry (green dot when online) fed by your account's device list, so your phone or another computer is reachable over the internet relay even when it is not on your local network. Sending delivers to all of your other linked devices.
decrypted ("N items could not be decrypted. Check that your passphrase matches your other devices.") instead of silently showing an empty list.
zero-identity rules as desktop), so iOS/visionOS builds appear in install statistics.
while the download runs (previously only sending had them), and a sender's cancel shows as "Cancelled by sender" mid-download.
up its saved resume data immediately instead of retrying a dead transfer.
that could not be cleared.
persist across restarts, with a search box, a display limit with paging, per-entry remove, and a Clear button for finished transfers (active, queued, and retryable entries are protected).
in folder (Save as goes away). If you later delete, move, or rename the file, its entry shows crossed out - like a browser download.
or app restart continues from where it stopped instead of failing. Interrupted transfers retry on their own (with a Resume now button) for up to 24 hours; integrity checking is unchanged.
transfer waits ("Queued - waiting for ... to come online") and starts automatically when the contact comes back, for up to 7 days.
"Cancelled by sender/receiver" instead of a confusing error, and a file offer answered on one of your devices disappears from your other devices ("Handled on your other device").
missing the permission grant that lets its UI receive ANY window events, so every drop was silently discarded on all platforms. The drop zone also no longer lights up unless it can actually accept the drop. Verified end-to-end with an instrumented build.
forwarded to the window, fixing silent failures (macOS especially).
email addresses are visible, with a green dot when a device is on your network or a contact is online.
says "waiting" and explains, instead of claiming "syncing".
of their devices can accept (previously only their primary could decrypt).
send tile) did nothing on any platform because the drop events never reached the window. Drops now stage and send as designed.
no longer shows "decryption failed" on their other devices.
device, instead of a misleading "syncing / synced just now". The normal sync status appears once a second device joins.
update cadence is verifiable.
background, which made the new version appear not to start. The app now shuts down leftover instances on launch and keeps its single-instance guard from being cleaned up by macOS.
notarized. Updates install without the repeated keychain and firewall prompts, because the app keeps one stable identity across versions. (Installing this version over an unsigned one may prompt one last time; after that, no more popups.)
window is open (and returns to a quiet menu-bar-only app when you close it), so it also appears in Cmd+Tab. Standard Edit menu means Cmd+C/V/X/A / undo / redo work in text fields.
(or click to choose) in one spot, then click who gets them. Your own devices and your contacts appear as one-click tiles (drag a file onto a tile to send it that way), and the old three separate file pickers are gone.
comes forward with a clear Accept / Decline card (and a desktop notification) instead of a small entry you had to hunt for. When a file arrives you can Open it or show it in its folder right away.
Settings) everywhere instead of a hex id.
account and link this device on its own -- no visit to the website and no copying a link code. It waits for you to confirm your email and finishes automatically. You can also sign in to an existing account, or still link an extra device with a code.
accept" in the Contacts list; when someone you are allowed to reach is on ClipNSync but has not linked a device yet, adding them or sending a file says exactly that (and how they fix it) instead of a generic not-available error; the Account section points at the new web-portal Discoverable toggle. Server side (already live): a Discoverable-by-email privacy toggle on the portal Profile page and a portal Contacts page for accepting or declining requests without the desktop app.
explains that the person may simply not be discoverable yet (the server never reveals whether an email has an account), and points at both next steps: invite by email, or send a request they can accept.
v5): when one device sends its pin/unpin/delete events or its sync-method state to a peer, the peer replies with its own state on the same connection. Networks where only one direction can connect (for example a firewall blocking inbound connections on one device while it can still connect out) now converge fully -- previously clips converged on such networks but pins and mode switches piled up undeliverable in one direction. Replies are validated exactly like inbound pushes (same caps, same per-event validation, same last-writer-wins gates). Devices still on protocol v4 keep today's one-way behavior automatically.
(protocol v4): pinning, unpinning, or deleting a clip pushes an event straight to trusted devices online on the same network, and a periodic sweep resends each device's recent window so peers that were briefly offline catch up. Last-writer-wins with delete-always- wins, matching the existing folder-marker semantics. Deletes always reach every device eventually via the folder tombstone as before; pin/unpin propagation beyond one hop currently relies on a shared cloud folder or on an intermediate device restarting (which re-seeds what it knows to its peers) -- a directly-connected device that never comes online alongside the originator will not otherwise learn of a pin/unpin over LAN alone. Devices still running an older protocol version fall back to folder-only marker sync automatically.
folder, WebDAV server, or "This network only (LAN)" using an app-managed local folder (no cloud client needed; trade-off: no off-network catch-up and no cloud backup while devices are apart). Switching backends is lossless: the app seeds the new backend with your pinned clips and recent history (additive only, never deletes anything) before cutting over, and the new target is probed and confirmed reachable before the previous, working setup is ever stopped -- a bad switch (unreachable WebDAV host, unwritable folder) leaves the old sync running and reports the error instead of leaving you unsynced.
trusted device in the group automatically over the LAN mesh (last-writer-wins, loop-safe: a device only ever re-forwards a switch it actually applied). WebDAV credentials travel only inside an AES-256-GCM blob sealed under the shared vault key, are probed with the candidate credentials before anything -- including the OS keychain -- is written, and land in each receiving device's own keychain only after that check passes. A switch to cloud-folder mode reuses each device's own existing folder path; a device that has none yet gets a notification to pick one instead of silently breaking. Remote-triggered switches are coalesced and rate-bounded (at most one applied switch per 20 seconds, always keeping the newest) so a misbehaving trust-group peer cannot force unbounded engine restarts.
small ping ({random install id, app version, OS, CPU architecture}) to clipnsync.com so we know what platforms and versions to support. On by default; never includes clipboard content, filenames, or anything tied to a linked account, and the install id is separate from your sync device id and never sent with any other request. Self-hosted/linked-account installs ping their own server instead of the public one. Turn it off any time in Settings > Privacy ("Share anonymous install statistics").
(the practical minimum for everyday installs remains hourly), and every automatic check now applies a small random jitter (up to about a sixth of the interval) so many devices never hit the update server at the same wall-clock moment.
uninstall ping on a full removal (never on an upgrade), respecting the install statistics opt-out above; macOS has no uninstall hook to attach to since the app is just dragged to the Trash.
an empty .pin marker file in the sync folder (same tombstone-style pattern as .del deletes), so every device that has pin syncing on follows the change on its next poll. Restored history after a restart re-applies existing markers so pins survive app restarts. A new "Sync pins across devices" Settings toggle (default on) lets a device opt out and keep pins purely local; turning it back on catches up on pin changes made while it was off. Retention pruning now respects pins everywhere: a pinned clip is never deleted for being over the history limit, on this device or any other. An explicit Clear remote history is a deliberate wipe and removes everything, including pinned clips and their markers. Deleting a clip everywhere also clears its pin marker, so a tombstoned clip never stays pinned-but-deleted.
file send (LAN/direct/relay), and folder-sync run is counted locally per day (bytes and count, metadata only, never content) in usage.db. On a trusted LAN, devices exchange usage counters via the mesh protocol so each device can display per-device stats for the whole trust group. With a linked clipnsync.com account, devices push counters to the server and the desktop app + web dashboard show cross-device aggregates; without an account, all stats remain local. Redesigned Usage tab: scoped to "This device" or "All my devices", windowed to Today or 30 days, relay quota meter at the top, and segmented Sent/Received bars by category (clipboard, file send, folder sync) with per-transport detail (folder/WebDAV/LAN/ direct/relay) and per-device breakdown.
automatically" checkbox plus a "Check every" interval (hour, day, week, month; default day); automatic checking also always checks once at launch, replacing the old "on every launch" option (existing configs migrate to daily). Found updates show an Update button instead of installing silently; silent auto-install is a separate opt-in toggle.
contact by email" flow is implemented end to end in code -- HPKE- sealed manifest + content key delivery, a tamper/reorder/truncation- evident chunked file cipher, a relay transport, a send/receive engine with TOFU hard-block on device-key change, configurable receiving modes (prompt with trusted auto-accept / always ask / auto-accept any verified), and a safe-write path for received files (sanitized filename, collision-safe, marked downloaded, never executable). Cross-implementation test vectors and a consolidated vector-compatibility test are checked in (test-vectors/filesend_v1 .json, test-vectors/filesend_chunks_v1.json, core/tests/filesend_vectors.rs). This has NOT yet been verified live between two real devices, and no packaged release ships it -- that verification is the remaining gate before file send is announced as working. The itemized entries below record each task's detail.
per-transfer content key and manifest (filename/mime/size/hash) to the recipient's device key, so the relay server only ever sees opaque ciphertext. Cross-implementation test vectors in test-vectors/filesend_v1.json. The manifest also carries the chunk stream's nonce prefix (task BC4), so that value never appears in cleartext on the wire either; the vector file was regenerated to match.
the file body itself. Each chunk is AES-256-GCM sealed under the transfer's content key with a nonce derived from a fresh per-transfer prefix XORed with the chunk sequence number, and an authenticated associated data of sequence number + final-chunk flag, so a relay (or anyone else) cannot reorder, drop, or truncate the stream without detection. Cross-implementation test vectors in test-vectors/filesend_chunks_v1.json.
drives a whole transfer end to end -- directory lookup, TOFU device key pinning with a HARD BLOCK on key change (no silent warn-and-continue on either the send or receive side), sealing the manifest, offering the transfer, awaiting accept/decline, streaming and decrypting chunks, and verifying the whole-file SHA-256 before ever treating a receive as complete (a truncated stream or a hash mismatch discards the file, never calls it done). Built entirely behind small traits (Directory/Signaling/TofuStore/ReceiveSink) so it is unit-tested with mocks, no live relay required; ApiDirectory/ApiSignaling wire it to the deployed clipnsync.com lookup/offer_send/offer_respond/poll endpoints, added to the file-send API client in this change.
how sealed chunks move between devices, plus RelayTransport, the first implementation, which ships opaque chunk bytes over the deployed clipnsync.com relay_put/relay_get/transfer_complete endpoints. No crypto in this layer; it moves ciphertext only. Tracks the last acked/delivered chunk sequence so an interrupted transfer can resume without loss or duplication (relay_put re-sends are idempotent server-side). Later phases (LAN mesh, QUIC) add transports behind the same trait without touching crypto or UX. get_chunk returns a 3-way ChunkFetch (Chunk/NotReady/Done) rather than collapsing "not uploaded yet" (404 chunk_not_found) and "stream complete" ({"done":true}) into the same result, so a receiver polling ahead of a slow sender cannot mistake a transient gap for end-of-stream and truncate the download.
clipnsync.com account with a one-time code or clipnsync:// link; Account section in Settings; device identity key + fingerprint.
engine into the desktop app. New commands (filesend_send, filesend_offers, filesend_respond, filesend_transfers, contacts_list/add/block/unblock, set_receiving_mode, set_download_dir) plus a background poll loop (~5s cadence) that drains signaling for incoming offers and applies the receiving-mode decision: prompt-with-trusted-auto-accept (default), always-ask, or auto-accept-any-verified, with a blocked sender always dropped silently in every mode. Received files go through a dedicated safe write path: the decrypted filename is reduced to a sanitized basename (path separators, leading dots, control chars, and Windows reserved device names all stripped/replaced), written to a temp file and renamed into place only after the whole-file hash verifies, never made executable, collision-safe ("name (2).ext", "(3)", ...), and marked with the OS downloaded-from-the-internet attribute (com.apple.quarantine on macOS, Zone.Identifier on Windows). TOFU peer device keys are pinned in config (not secret); the HARD BLOCK on a changed key from task BC4 is unchanged -- this only adds the storage backing it. No UI yet (task BC6).
"Send to a contact" section for the account-based relay flow (separate from the existing LAN/clip-file quick send, which needs no account): recipient email, a multi-file picker (new read-only pick_files_for_send command), a transport badge ("relayed"), and friendly messages for PeerNotAvailable, PeerKeyChanged (a prominent security warning -- transfer blocked, verify before retrying), OfferDeclined, and OfferTooLarge. Incoming offers render as an accept/decline/always-trust prompt; the decrypted filename and sender's claimed email are rendered with textContent only, never innerHTML, everywhere they appear (offers, transfers, contacts). Added Contacts (add/list trusted, list/unblock blocked -- blocking is offered from an incoming offer, since that is the only place a blockable account id is known) and a receiving-mode selector in Settings (prompt-with-trusted-auto-accept / always-ask / auto-accept-any-verified, labeled risky), reusing the existing download-folder picker's underlying config field via the new set_download_dir wiring. get_status gained a receiving_mode field so the selector can reflect the current setting without a new getter command.
platform's terms - "Cmd + Shift + V" on macOS, "Ctrl + Shift + V" on Windows/Linux - instead of the raw cross-platform token. Change it by clicking Change and pressing the combination you want (Esc cancels), with a Reset to the default. If the combination is already claimed by another app or is invalid, the change is refused with a clear message and your previous shortcut is kept, so you are never left with no binding.
already on ClipNSync. If they are, you send a contact request as before. If they are not, ClipNSync opens your own default mail app with a prefilled invite - the message is sent by your mail account, never by our servers. A "Send request anyway" option covers people who exist but have turned off directory discovery.
accept or decline in the app, and only after mutual acceptance can either side send them a file. Incoming contact requests show up alongside incoming file offers so they can be actioned from the same place. Blocking a contact is a local-only setting (not synced to the server or the other device) and stops their offers from prompting.
on the same network, falls back to a hole-punched direct connection across the internet when NAT allows it, and falls back again to the encrypted relay when neither direct path is available. The relay never sees plaintext file content, filenames, or keys -- only ciphertext and the routing metadata needed to move it.
today's relay quota used and 30-day transfer totals -- sent/received counts and bytes, and success rate -- so you can see where a transfer went and whether the relay is close to its daily cap.
contacts; picking one opens a file picker and starts the send immediately, without opening the main window first.
tab on macOS and Windows. The previous version relied on a backend-to-frontend event that was not always delivered (the window just opened on its default tab). The target tab is now stored and the window applies it on its next refresh - no event needed.
clips to every online device immediately instead of waiting for the timed sync. Offline devices are still caught up automatically when they return.
with you (an anti-entropy sync marks everything the peer holds as delivered), so it no longer lingers after the peer already has the clip.
LAN delivery reliability, Phase 2 (anti-entropy):
just push. On its retry sweep each device asks every trusted peer for anything it is missing and pulls it. A device that was asleep now catches up from ANY peer that has the clip - the device that first copied it no longer needs to be awake.
that are never online at the same moment.
device still syncs (v1 push) with a peer that has not updated yet, so updating devices one at a time does not break LAN sync.
the wire; everything stays AES-256-GCM in memory, on disk, and on the network. New unit tests cover version negotiation and the have-list / pull exchange.
offline longer than the recent window.
LAN delivery reliability, Phase 1 (offline catch-up):
trusted device, which ones each has acknowledged receiving.
briefly off the network is caught up on everything it missed the moment it is back online (while the sender is running, within the outbox window). Re-delivery is safe - duplicates are collapsed on receipt.
"N clips pending", and "last seen 5m ago" for offline devices.
per-push acknowledgement, and clip bytes stay AES-256-GCM encrypted in memory, on disk, and on the wire throughout.
that tab. Previously, when the window had to be created fresh (it had been closed), the navigation event fired before the new window finished loading and was lost, so it just showed the default tab. The target tab is now passed in the window URL and applied on load.
expand/collapse choices persist across opening and closing the window.
Privacy, Devices - instead of one long scroll. General is open by default; click a section header (+/-) to expand or collapse it, so you see a short map of categories and only the controls you want. All the same settings are still here, just grouped and foldable.
and the privacy summary), so version info is available before you have created a vault. "About ClipNSync" from the tray scrolls to it when the app is not yet set up.
the Settings tab (bringing it to the front if hidden or minimized).
clear which Pin/Delete buttons belong to which clip, without adding vertical space.
the device/timestamp and Pin/Delete on a second line underneath. Long clips (URLs, commands, sentences) are no longer cut short to make room for the buttons.
front (showing it if hidden or minimized) and jumps straight to the About tab. "Open" also unminimizes.
transfer rows have more breathing room and never crowd the right edge of the window.
UX pass (from a first-run/confusion audit):
staring at an empty menu bar.
with WebDAV and pairing-code entry moved under "Advanced setup".
minimum length, warns that it is your encryption key and cannot be recovered, and the button reads "Create vault" (vs "Unlock" for an existing vault).
folder sync, separate from the clipboard); a Settings toggle shows it.
Send tab, so accepts are not missed.
Privacy / Clip picker / Limits / Updates), with one-click ignore- pattern presets, and the window is a little taller.
LAN device trust.
Added:
folders (Nextcloud Virtual Files, OneDrive Files On-Demand, Dropbox, Google Drive), ClipNSync now marks its own clip files PINNED via the Cloud Files API - the same effect as right-clicking "Always keep on this device", with no admin rights. This keeps .cns files hydrated locally so reads never trigger on-demand fetches, which is what caused the "cloud file provider exited unexpectedly" (os error 404) errors. Best-effort and a no-op on plain local folders, WebDAV, and non-Windows platforms. Pairs with the v0.7.20 skip-and-retry so a provider hiccup is now both prevented and, if it still happens, handled quietly.
Added:
updates (manually, on every launch, daily, weekly, or monthly; default daily). A found update now shows "Update available: vX.Y.Z" with an Update button instead of installing silently; silent auto-install is a separate opt-in ("Install updates automatically"). A "Check now" button runs an immediate check.
Changed:
file-on-demand provider (Nextcloud Virtual Files, OneDrive Files On-Demand, iCloud optimized storage) is briefly offline or busy, reading a placeholder can return a transient OS error such as "the cloud file provider exited unexpectedly" (Windows os error 404). The sync engine now skips that one file and retries on the next poll instead of failing the whole cycle, and the UI shows a calm "waiting for your cloud sync app" note rather than the raw error.
surfaces, refined buttons, list rows, cards, and tabs. No behavior change; styling only.
Added:
the one-time code is now also shown as a QR image, so you can scan it (e.g. with a phone) instead of retyping. The QR encodes the plain code and is generated entirely on-device. See docs/PAIRING.md.
Added:
sync arrows on a blue gradient) replaces the placeholder. Generated from desktop/icons/logo.svg into all platform assets (png/icns/ico) via desktop/icons/build-icons.sh; the full set is wired into tauri.conf.json, so Finder, the dock, the dmg, the Windows installer, and the About box now show it.
(value prop, features, how-it-works, security, downloads) using the inline SVG logo. Enable GitHub Pages from /docs to publish it.
app screenshots to follow from a running build.
Added:
regular expression. A copied text clip whose content matches any of your patterns is not captured, stored, or synced. Set them (one regex per line) under Settings -> Ignore patterns; each is validated before saving and applied live. Handy for skipping card numbers (\d{13,16}), key material (BEGIN PRIVATE KEY), or any per-user secret shape. Content (text) rules ship now; source-app exclusion may come later.
Added:
device without retyping your vault passphrase. On a set-up device, Settings -> "Pair a device" shows a one-time code and seals the vault key into a short-lived, code-encrypted bundle in the sync folder (Argon2id + AES-256-GCM, the same primitives as clips -- no new crypto). On the new device, setup -> "Join with a pairing code" enters the code to recover the key and start syncing. The key travels only as ciphertext; the passphrase is never shown to the new device. 60-bit codes, 10-minute expiry, bundle consumed on use. Needs a shared local sync folder (WebDAV-only pairing comes later). See docs/PAIRING.md. New core module clipnsync_core::pairing.
Added:
markers that password managers and other apps set on secret content, so passwords, one-time codes, and anything flagged concealed or transient are never captured, stored in history, written to the sync folder, or sent over the LAN mesh. Works on macOS (nspasteboard Concealed/Transient/AutoGenerated types) and Windows (ExcludeClipboardContentFromMonitorProcessing). New Settings toggle "Skip passwords and sensitive clips" (default on). The gate runs in the capture path before any encryption or write, so nothing sensitive leaves the device. Linux has no reliable cross-desktop marker yet, so the setting is a no-op there (see docs/KNOWN_LIMITATIONS.md).
Added:
configurable) anywhere to open a small search-as-you-type overlay of your recent clips. Arrow keys + Enter or a click copies the clip; Esc or clicking away dismisses it. Copy-only -- you then paste with Cmd/Ctrl+V, so no macOS Accessibility permission is needed. Toggle and change the shortcut in Settings.
Added:
recent text and image clips; click one to copy it instantly, without opening the window. The list refreshes as your history changes. Files are not shown (they do not go on the clipboard; use the File Send tab). This makes ClipNSync usable as an everyday clipboard manager straight from the menu bar.
Added:
- N peers on LAN", or a red "Sync error - folder or server unreachable" when the last backend poll failed. Shows the last successful sync time, backend reachability, and connected LAN peers.
Fixed:
toggle in the settings window (#18). Previously toggling pause in the window left the tray checkmark stale.
Added:
the retention limit, and show at the top of the list with a "pinned" marker. Pin state is local to the device and survives restarts.
it from the sync folder with a tombstone, so it is also dropped from your other devices, plus from local history. Works for clipboard entries and file transfers. (Previously only "clear everything" existed.)
Added:
If the accept gate is on, the notification says the file is ready to accept; if auto-save is on, it says the file was saved. Toggle with "Notify me when a file arrives" in Settings (default on). Clipboard text and images stay silent -- they just appear on your clipboard as expected. On macOS the app asks for notification permission once at startup.
Fixed:
[darwin-aarch64...] were found" when Check for updates was pressed while a release was still building (#32). The release is now created as a draft, all platform builds upload to it, and it is published (marked latest) only after every platform finishes -- so the updater never sees a latest.json that is missing platforms. No app change; the fix is in the release workflow and takes effect from this release on. If you hit the error before, just press Check for updates again once the release has finished.
Fixed:
modern public.file-url pasteboard items first (what current apps and Finder set), falling back to the legacy NSFilenamesPboardType. Some sources set only the file URL, so the previous legacy-only read could miss them. Verified against the live pasteboard on-device.
Tested:
device identities share one folder, one sends a copied file, the other receives and accepts it; asserts loop prevention, the accept gate (nothing on disk before accept), and byte-identical delivery.
Added:
file manager (text/uri-list on the clipboard) appear in "On your clipboard" with a Send button, matching Windows and macOS. Reads the clipboard via wl-paste (Wayland) or xclip (X11); if neither tool is installed the feature is a silent no-op and the picker/drag-drop still work.
Added:
appear in an "On your clipboard" list with a Send button (#31). Nothing is sent until you press Send -- you see the copied file and choose. Reads the OS clipboard file list per platform (CF_HDROP on Windows, NSFilenamesPboardType on macOS); Linux still uses the picker or drag-and-drop. Only the path list is read; the file bytes are read and encrypted only when you send.
Changed:
They now appear in the File Send list as pending, with an "Accept & save" button; nothing touches disk until you accept, so a file is never blindly downloaded onto your other computers. The encrypted bytes still sync so the device can show what is available; only the plaintext write is gated. A "Save as..." action remains for choosing a different location. Settings has a new "Auto-save received files" toggle to restore automatic saving (default: off / accept).
Note: sender-side detection of files you copy in Explorer/Finder (Ctrl+C) with a Send button is the next step, tracked in #31.
Fixed:
outside the window, misaligned with the card (#29). The two-column grid now uses minmax(0,1fr) tracks so a long option no longer forces the grid wider than its container.
Added:
The drop zone highlights while dragging; dropped files are read and encrypted in Rust just like the picker, and the size cap still applies. (Dropping on the tray/menubar icon is not supported by the tray API; use the window.)
path fields (#27), for users who cannot or would rather not paste a path. Opens a native folder picker and fills the field.
Fixed:
white-on-white and only readable on hover (#26). The selects now use theme-aware system colors.
likely -- applying a received clip now retries the clipboard up to 12 times with a growing backoff (about 3.5s total) so ordinary contention from other apps resolves silently instead of surfacing.
Added:
automatically when you log in, per-user with no admin: a LaunchAgent on macOS, the per-user Run key on Windows, XDG autostart on Linux. The OS is the source of truth; the checkbox reflects and toggles it. Uses the official tauri-plugin-autostart.
Added:
other devices are now decrypted and saved automatically. The default is the OS Downloads folder; change it via "Save received files to" in the File Send tab. The per-transfer "Save a copy" dialog now opens in that folder too. Auto-save picks a non-clobbering name ("report (1).pdf") when a file of the same name already exists, and never re-saves your own sent files or the backlog on restart. Auto-save sanitizes the received filename to a single basename before writing, so a peer cannot use a crafted name (path separators, "..", or an absolute path) to place a file outside the chosen folder.
Added:
clear), File Send (send + transfer list with click-to-save), Folder Sync (job editor: mode/trigger/conflict behavior, Sync Now, run history; mirror/two_way saves require confirmation and archive instead of deleting), Settings (all toggles, limits, devices, updates), About.
Known gaps (tracked in #23): delete-selected clips, live transfer progress, preview-of-plan before destructive runs (confirm dialog guards mirror/two_way meanwhile), ask_user conflict prompts.
Added:
three-way comparison (edits propagate both directions, deletes distinguished from creations via last-sync state, archived by default) and conflict handling: source_wins, destination_wins, newest_wins, keep_both (loser preserved as .conflict on BOTH sides); ask_user defers to the upcoming UI.
snapshots, run history), scheduler thread with manual/timer/ on-change triggers (USB plug-in counts as a change), and app commands (list/upsert/delete/run/history) ready for the tab UI.
file-readiness gating (stable_seconds), exclude patterns, archive folder exclusion; copy/mirror/move planner; executor with .syncing safe-copy verification and archive-instead-of-delete default. Not yet exposed in any UI; ships with the tab redesign.
Added:
file (25 MB cap); receiving devices click the history entry to save it. The original filename travels INSIDE the encrypted payload per protocol section 5 - servers and folders never see it. Files never touch the clipboard. Auto-capture of files copied in Finder/Explorer remains open in #4.
Added:
WebDAV server (nginx/Apache) instead of a synced folder. Same encrypted .cns files, same four operations, no-overwrite puts via If-None-Match. Configure URL + user in setup; the password goes in the OS keychain only. Implemented; not yet validated against a real server.
Added:
as their encrypted .cns bytes (decrypted only in memory with the vault key) so history survives restarts AND outlives sync-folder pruning. Clear remote history also clears the local store.
Fixed:
including this device's own clips, in chronological order. All devices show the same list after restarts (field report: Mac and Windows histories diverged because restarts emptied the in-memory list and own clips were never re-ingested). Full persistent history (#19) still planned.
Added:
(allowlisted URL only)
Fixed:
re-copied or re-received identical clips move to the top instead of stacking (field report). Near-identical text (differing selections) still lists separately, correctly.
Added:
About ClipNSync item opening the window with the About section
Added:
(auto-update still installs silently when enabled)
GitHub link, privacy summary
Fixed:
now a second launch focuses the existing window (single-instance)
Fixed:
("held by another party"); stale error banners clear on success
Added:
Unreleased work toward v0.1. Session summaries append below.
Added:
clear), File Send (send + transfer list with click-to-save), Folder Sync (job editor: mode/trigger/conflict behavior, Sync Now, run history; mirror/two_way saves require confirmation and archive instead of deleting), Settings (all toggles, limits, devices, updates), About.
Known gaps (tracked in #23): delete-selected clips, live transfer progress, preview-of-plan before destructive runs (confirm dialog guards mirror/two_way meanwhile), ask_user conflict prompts.
Added:
with header-as-AAD, vault, watched-folder backend, sync engine (loop prevention, debounce, size cap, pruning, tombstones)
storage, text + image sync, history click-to-copy, pause, text-only mode, clear remote history, metadata-only logging
Fixed:
Changed:
v0.3.2: retry clipboard writes on Windows lock contention (first real Windows hardware report - the installer works on Win11!); error banner now clears on next success instead of persisting.
v0.3.1 released via the tag workflow (18 assets, latest.json serves 0.3.1): the auto-update test target. Docs gate hardened to reject stale version references after three drift catches by the owner.
Shipped: headless CLI, Linux x64+ARM64/Pi and macOS universal CI builds, iOS app (builds, runs in simulator), Android debug APK, v0.2.0-alpha (10 assets) and v0.3.0 (18 assets incl latest.json), signed auto-update end to end, secret-scanning enforcement (pre-push hook + CI gitleaks), docs/BUILDING.md + CODE_SIGNING.md. Fixed: prerelease flag broke the updater endpoint (fdad16a); UniFFI Kotlin Throwable.message collision. Open: WebDAV (#10) and file clips (#4) remain UNIMPLEMENTED; hardware validation pending on all non-macOS platforms; release workflow lacks CLI+Android (#15). Updater key backup lives in ~/.clipnsync-signing (owner must back up).
What changed:
the vault key, mutual challenge-response, framed clip transfer), desktop mesh (mDNS advertise/browse, TCP listener, trusted-peer push, manual host:port fallback), engine ingest with LAN/folder dedup, devices UI with Trust/Revoke and add-by-IP.
shown (default 10), applied at runtime.
WebDAV; cloud APIs/relays remain forbidden.
Tests run: cargo test --workspace (48 passing, 1 ignored), clippy -D warnings clean, loopback mesh e2e (probe/auth/trust-gate/deliver) passing, gitleaks clean.
Commits: 9bcfd05 (settings UI), 39920b6 (core lan), d33b9e3 (desktop mesh), plus this docs commit.
Issues: #21 closed; #20 remains open for two-machine mDNS validation and the transport-encryption wrapper.
Known problems:
cross-machine mDNS not yet validated on real hardware.
#1/#2 Windows hardware test).
Next recommended task: two-machine test - macOS GUI walkthrough on this Mac plus the Windows installer on a second machine, exercising both folder sync and the mesh (trust both ways, watch for instant delivery).
What changed:
(one Rust core + Tauri shell now, native shells later over the same core; single-file .cns format).
simulated second device: text and images both directions, zero echo clips.
NSIS per-user installer (unvalidated on real Windows, #1/#2).
Tests run: cargo test --workspace (40 passing), clippy -D warnings clean, gitleaks full-history + working-tree scans clean.
Commits: b8dada0..HEAD on main (specs, core, vectors, engine, desktop, images, CI, fixes #16/#17, logging, hygiene, tracking docs).
Issues created: #1-#19 (backlog per docs/ROADMAP.md). Closed: none; #16 and #17 are fixed in these commits and will be closed on push.
Known problems:
Next recommended task: run docs/MACOS_GUI_TEST.md by hand (#3), then install the CI NSIS artifact on real Windows (#1, #2).