Repository navigation
Releases
2.3.1.2781
Highlights 🌟
-
📋 Floating paste button fixes
Fixed interaction issues with the floating paste button and its panel;
on Wayland its pastes now reach native Wayland apps, because clipboard
writes go straight into the Wayland clipboard instead of an XWayland
selection that KWin mirrors only while CrossPaste has the focus
(#5283 #5284 #5285 #5286 #5292 #5293). -
🪟 MSIX packages declare their firewall rules
Inbound TCP/UDP forbin\CrossPaste.exeon domain and private networks
is declared in the package, so Windows stops re-prompting after every
versioned-path update and no longer accumulates dead prompt rules. The
CLI execution aliases moved into the main Application, because the
Store rejects a hidden second Application as headless; release CI now
asserts both (#5287 #5288 #5289 #5290). -
🔍 Search window double-click paste and keyboard-driven top bar
Double-click paste honors the system double-click interval and reads
Shift from the click itself; every search window shortcut goes through
one resolver keyed by the focused zone, which adds keyboard navigation
across the type filter, tags and settings (#5277 #5278 #5279 #5280
#5281 #5282).
Bug Fixes 🐛
- 🐛 Write the Wayland clipboard natively so background writes reach Wayland apps (#5293)
- 🐛 Fold the MSIX CLI aliases into the main Application so the Store accepts it (#5290)
- 🐛 Declare MSIX firewall rules so Store updates stop re-prompting (#5288)
- 🐛 Highlight the clicked row in the paste panel (#5286)
- 🐛 Make the macOS paste panel stay on screen and paste into the focused app (#5284)
- 🐛 Read Shift from the click itself in the search window list (#5280)
- 🐛 Honor the system double-click interval in the search window (#5278)
- 🐛 Keep development.properties and stray .claude folders out of release jars (#5273)
New Features ✨
- ✨ Drive the search window top bar from the keyboard (#5282)
- ✨ Tint tag chips with their color and give emphasized chips a heavier edge (#5274)
Multiplatform · Refactor · Code Style 🔨
- 🔨 Route search window shortcuts through one key resolver keyed by focused zone (#5281)
Build & CI 👷
- 👷 Assert the Store MSIX keeps its firewall rules (#5289)
2.3.0.2767
Highlights 🌟
-
🧩 Local process plugins in the paste context menu
A plugin is a folder with amanifest.jsonand a script or program;
CrossPaste runs it with the paste on stdin and applies stdout to the
clipboard, history, a notification or the browser. Plugins start
disabled and are managed under Extensions → Plugins. A bundled
Translate plugin offers a target-language submenu (#5210 #5212 #5228). -
🔄 Catch up on missed pastes when a peer reconnects
Desktop pulls a trusted peer's pastes through an incremental cursor
whenever the peer becomes connected, filling in what was missed while
it was offline; remote pastes with invalid content are discarded
instead of being written to the clipboard (#4897). -
⌨️
crosspasteis the CLI on Windows installs
Installer and Microsoft Store packages register bothcrosspasteand
crosspaste-clias CLI aliases, the Store package ships the CLI, and
the control socket moved out of the MSIX-virtualized temp directory so
CLI commands no longer report the app as not running (#5190 #5191
#5192 #5193 #5195). -
🐧 Linux link/file opening, RPM packages and a dnf repository
Links, HTML, RTF and files open through xdg-open, "show in file
manager" selects the file via FileManager1, EL9 RPM packages for
x86_64 and aarch64 are published alongside the deb, and RPM installs
subscribe to a signed dnf repository (#5184 #5185 #5186 #5187). -
📋 Paste injection waits for the target app
On macOS and Windows the paste keystroke is injected only after the
previous app is back in the foreground (otherwise the user is asked to
paste manually), shortcut-triggered pastes wait for the shortcut keys to
be released, X11 waits for the target window, and the keystroke itself
is sent in one SendInput call on Windows and as flagged events on macOS
(#5247). -
🪟 Windows MSIX installs again
The 2.2.0 and 2.2.1 installer packages failed with 0x80080204 on
current Windows builds because two appExecutionAlias extensions were
declared under one Application. The manifest now declares the CLI
alias in its own Application, so the package installs and updates
cleanly (#5188 #5189).
Bug Fixes 🐛
- 🐛 Keep keyboard focus off search window controls so Enter still pastes after a click (#5267)
- 🐛 Exclude all CrossPaste windows from the Windows previous-app record (#5264)
- 🐛 Switch the macOS activation policy when the main window hides so the first search window show is not dismissed (#5262)
- 🐛 Post the macOS paste shortcut as flagged key events without separate modifier key events (#5252)
- 🐛 Send the Windows paste keystroke in one SendInput call with reverse release order, scan codes and extended-key flags (#5250)
- 🐛 Inject the paste only after the previous app is back in the foreground on macOS and Windows (#5248)
- 🐛 Wait for the target window to become active before injecting the X11 paste keystroke (#5246)
- 🐛 Wait for the shortcut keys to be released before injecting a shortcut-triggered paste (#5244)
- 🐛 Stop macOS search focus rechecks from blocking the EDT on AppKit (#5242)
- 🐛 Require a drag threshold before starting drag-and-drop in the search window (#5239)
- 🐛 Keep the newest paste fully in view when prepended at the list start (#5237)
- 🐛 Discard remote pastes with invalid content instead of writing them to the clipboard (#5234)
- 🐛 Fix macOS search window dismissal and tray toggle races (#5215)
- 🐛 Report Windows plugin script failures as a single line (#5229)
- 🐛 Normalize launcher resources dir on all platforms and drop skiko fallback (#5226)
- 🐛 Stabilize Windows search window activation and dismissal (#5227)
- 🐛 Unmount the token popup when no pairing card is visible (#5223)
- 🐛 Skip non-web URLs in clipboard previews (#5224)
- 🐛 Close the search window when focus is lost during the startup grace period (#5200)
- 🐛 Toggle the search window from the tray icon on Linux (#5206)
- 🐛 Hide the pairing-code card after the user rejects it (#5202)
- 🐛 Respect Plasma fractional scaling and confirm pairing with Enter (#5201)
- 🐛 Normalize Super key events on XWayland (#5199)
- 🐛 Declare the MSIX CLI execution alias in its own Application (#5188)
- 🐛 Start the CLI socket from the user data directory on Windows (#5195)
- 🐛 Show files in the file manager on Linux (#5186)
- 🐛 Open browser links, HTML, RTF and files with xdg-open on Linux (#5184)
New Features ✨
- ✨ Make the bubble editor modal over the search window and keep it stacked on top (#5266)
- ✨ Attribute OCR and plugin pastes to CrossPaste and show its logo as their source icon (#5240)
- ✨ Catch up on missed pastes when a peer reconnects (#5233)
- ✨ Plugin submenu actions and a target-language picker for Translate (#5221)
- ✨ Run local process plugins from the paste context menu (#5214)
- ✨ Scan local plugins and check their compatibility (#5213)
- ✨ Draw the logo on the brand gradient with a one-stroke trace animation (#5207)
- ✨ Make
crosspastelaunch the CLI on Windows MSIX packages (#5192) - 💄 Outline the main window on Linux so it stands out from other windows (#5204)
- 🔥 Remove the sort toggle from the search window (#5235)
Multiplatform · Refactor · Code Style 🔨
- 🔨 Rename PasteAutoPullService to PastePullTrigger (#5263)
- 🔨 Expose the pairing v3 dialog state as a StateFlow (#5231)
- 🔨 Assemble the paste context menu through PasteMenuContributor (#5211)
- 🔨 Provide static and animated CrossPasteLogo composables (#5209)
- 🔨 Make AbstractGlobalCopywriter Compose-free and publish the language as a StateFlow (#5179)
- 🔨 Move MessageType's Compose colour and icon helpers into ui.base (#5180)
Build & CI 👷
- 👷 Refresh README contributors when an outside contributor's PR is merged (#5232)
- 👷 Publish a signed dnf repository for the RPM channel (#5198)
- 👷 Build the Microsoft Store MSIX in release CI and publish from it (#5194)
- 👷 Build EL9 RPM packages for Linux x86_64 and aarch64 (#5187)
Dependencies ⬆️
- ⬆️ Upgrade Compose Multiplatform to 1.12.2 and Navigation to 2.10.0-rc01 (#5218)
- ⬆️ Upgrade Kotlin to 2.4.21 (#5216)
- ⬆️ Upgrade the Gradle wrapper to 9.8.1 (#5217)
- ⬆️ Upgrade SQLDelight to 2.4.1 (#5220)
- ⬆️ Bump source-map-js to 1.2.2 in the web lockfile (#5197)
- ⬆️ Bump imageio from 3.15.2 to 3.15.3 (#5256)
- ⬆️ Bump com.github.ben-manes.caffeine:caffeine (#5258)
- ➖ Replace ph-css with a built-in inline style parser (#5259 #5261)
New Contributors 👋
- @BiFangKNT made their first contribution in #5184
Full Changelog: 2.2.1.2706...2.3.0.2767
2.2.1.2706
Highlights 🌟
-
📋 Floating paste panel
A non-activating floating button lists the clipboard history and
pastes a row into the focused app on click, with a native
right-click menu. It works on macOS, Windows and Linux (X11 and
Wayland, the latter through the RemoteDesktop portal) (#4995 #5039
#5062 #5063 #5064 #5066 #5068 #5076 #5078 #5079). -
⬇️ Background update downloads (Windows portable zip)
A newer release is downloaded, verified and extracted in the
background as soon as the periodic check finds it, throttled to
1 MB/s, with HTTP range resume across restarts and dropped
connections; the prompt then offers a one-click restart. A General
settings switch turns automatic downloads off (#5090 #5091 #5092). -
🔒 Password-manager hints and source exclusion
Copies that password managers mark as "do not record" (Bitwarden,
1Password, KeePassXC and others) are now honored on Windows, macOS
and Linux: they are neither stored nor synced. The Clipboard sources
page was redesigned so excluded apps can be picked from the running
apps or browsed for, and match rules skip any source whose name
contains a given text (#5013 #5015 #5017 #5020). -
📁 Large-file destination
The large-file Downloads switch is replaced by a destination path:
files above the backup size limit go to the folder you choose, or
to the system Downloads folder when it is empty. Receive-side
same-name conflicts now persist the renamed record correctly and a
retry can no longer truncate an existing file (#5007 #5038 #5045
#5047 #5051). -
⚙️ Settings information architecture
The Advanced group became Clipboard with Recording, Sync and
Storage pages, size limits moved into one Storage section, Clipboard
sources moved to Recording, and every row and page title was
reworded to read without its subtitle. The settings content area
now uses a grey ground with white section cards, and the theme
switch is the mobile sun/auto/moon slider (#5046 #5048 #5049 #5052
#5021 #5022 #5023 #5024 #5028 #5034 #4991). -
🖥️ Devices page and multi-homed hosts
The Devices page acts on what it shows: the local device heads the
list, refresh keeps the list, removal asks for confirmation, nearby
devices can be blocked in place. Peers now learn the address they
dialed on multi-homed hosts (Windows ICS, hotspots), the interface
list follows network changes, and a manual add with no usable
address fails with a message (#4935 #4951 #4953 #4955 #4957 #4959
#4993 #5026 #4996 #4998 #5000 #5009). -
🔄 Sync reliability
Received pastes are acknowledged only after they are durable, the
pairing initiator advertises its own address on the v3 commit so
one-way-mDNS networks sync both ways after pairing, stale sync rows
no longer cause duplicate pushes, WebSocket pushes are acknowledged
so receiver failures fail the task, and push session finalize and
expiry are serialized (#4894 #4895 #4915 #4936 #4937 #4945 #5086). -
🛡️ Data integrity and storage reclaim
Storage migration saves the new path before deleting the old store,
an unreadable config is never overwritten with defaults, deleted
pastes take their directories with them, import/export no longer
leave broken records and reject paths escaping managed storage,
remote LOADING rows always reach a terminal state, concurrent
releases of the same content no longer delete each other, and a
startup failure before logging leaves a log and exits non-zero
(#5094 #5095 #5096 #5097 #5098 #5099 #5124 #5125 #5126 #5127 #5130
#5131 #5132 #5133 #5140 #5141). -
🔁 Relay and sync hardening
Clipboard relay now forwards non-file pastes and carries a seen set
so relays never loop, a removed device can no longer be re-inserted
by a racing SyncInfo write, failed polls back off quickly, discarded
pushes free their pre-allocated large-file slots, and headless mode
stops logging the pairing token (#5108 #5109 #5118 #5119 #5122 #5123
#5151 #5152 #5155 #5156). -
🔍 Search window
FTS terms are quoted so punctuation no longer breaks search, the
selection, query reset and tag filter follow live data, closing
without pasting returns focus to the previous app, the window closes
together with the edit bubble, and the panel button recovers after
its display is unplugged (#5093 #5116 #5117 #5145 #5146 #5147 #5148). -
🧠 Memory and runtime
Coil's memory cache limit is no longer inflated to 435 MiB, the
desktop server engine moved from Netty to CIO, Skiko's periodic
System.gc() runs as a concurrent cycle, and the bundled runtime is
JBR 25 (#4908 #4911 #4912 #4913 #4831 #5042 #5044). -
🌐 UI copy revision
English and Chinese copy was revised across the app and the eight
other languages were revised against the new source, with i18n
consistency checks and a style guide added (#4961 #4963 #4965 #4967
#4970 #4972 #4974 #4976 #4979 #4980 #4985 #4986 #4987 #4988).
Bug Fixes 🐛
-
🐛 Capture copies from native Wayland apps via the data-control protocol (#5173)
-
🐛 Report the displayed size of EXIF-rotated images in the side preview (#5162)
-
🐛 Keep a removed device from being re-inserted by a racing SyncInfo write (#5156)
-
🐛 Back off quickly after a failed poll of a regular device (#5152)
-
🐛 Close the search window with the bubble and re-place the panel button when its display is gone (#5148)
-
🐛 Keep the search window's selection, query reset and tag filter in step with live data (#5146)
-
🐛 Stop concurrent releases of the same content from deleting each other (#5141)
-
🐛 Discard a macOS pasteboard snapshot when another write lands during the read (#5139)
-
🐛 Keep CF_HTML offsets in step with the bytes AWT writes on Windows (#5137)
-
🐛 Leave a startup-failure log and exit non-zero when startup fails before logging (#5133)
-
🐛 Save the new storage path before deleting the old store during migration (#5131)
-
🐛 Refuse to apply a zip update whose staging lost its exe (#5129)
-
🐛 Reclaim paste directories and stop import/export from leaving broken records (#5127)
-
🐛 Give remote LOADING rows a terminal state and stop orphaning their files (#5125)
-
🐛 Relay non-file pastes and make clipboard relay loop-free (#5123)
-
🐛 Delete pre-allocated large-file slots when a push is discarded (#5119)
-
🐛 Return focus to the previous app when the search window is closed without pasting (#5117)
-
🐛 Stop logging the pairing token in headless mode (#5109)
-
🐛 Reference MCP-added files at their original path (#5106)
-
🐛 Refresh companion flavors when editing a paste from the UI (#5104)
-
🐛 Remove tag links when a tag or paste is deleted (#5102)
-
🐛 Never overwrite an unreadable app config with defaults (#5099)
-
🐛 Keep the owning record when a file is copied out of CrossPaste storage (#5097)
-
🐛 Reject import records whose paths escape managed storage (#5095)
-
🐛 Quote FTS search terms so punctuation no longer breaks search (#5093)
-
🐛 Fix portable update offline trigger, mirror affinity, cross-mirror resume and rate limiter burst (#5092)
-
🐛 Self-register the initiator's address on the pairing v3 commit so an acceptor that never sees its mDNS can reach it (#5086)
-
🐛 Fix multi-monitor placement, clipping and focus handling for Linux paste panel menu (#5079)
-
🐛 Close the floating button's menu on Linux when the user clicks elsewhere (#5078)
-
🐛 Let the floating button fade back on Linux when no pointer exit arrives (#5076)
-
🐛 Offer a URL paste item as plain text so non-Java apps can paste it (#5072)
-
🐛 Keep GuidePasteDataService.initData from throwing into host startup code (#5070)
-
🐛 Tell the user to paste manually when no X11 window can be targeted (#5066)
-
🐛 Create the paste panel windows as override-redirect on Linux so a click keeps the target app focused (#5064)
-
🐛 Give the paste panel button menu an opaque theme background on Linux (#5063)
-
🐛 Fix the paste panel corners and button menu glyphs on Windows (#5062)
-
🐛 Run the ws-session sync handlers on the test dispatcher to fix a CI flake (#5058)
-
🐛 Route the macOS application menu About item to the About page and localize its title (#5054)
-
🐛 Let the About page scroll so the app name and version are not squeezed out (#5053)
-
🐛 Only offer the large-file destination picker where a storage path manager exists (#5051)
-
🐛 Pass --add-opens as a single token so packaged builds start on JBR 25 (#5044)
-
🐛 Open the Accessibility privacy pane via open(1) since Desktop.browse drops the deep link on macOS 26 (#5036)
-
🐛 Cap the device name marker with a layout modifier so the row can be measured intrinsically (#5026)
-
🐛 Stop caching the update site's fixed-name files for 30 days (#5006)
-
🐛 Cap the device name marker at half the title line so it cannot starve the name (#4993)
-
🐛 Key side preview remember blocks on the data they actually read (#5012)
-
🐛 Extract HTML text from the body only, trim it and unescape entities (#5010)
-
🐛 Refresh the network settings interface list on network changes (#5009)
-
🐛 Fail the manual add when the peer names no address (#5000)
-
🐛 Answer /sync/syncInfo with the address the peer dialed (#4998)
-
🐛 Update the browser extension to the renamed i18n keys and check its references (#4974)
-
🐛 Settle push session finalize and expiry discard under one terminal lock (#4945)
-
🐛 Acknowledge received pastes only after they are durable (#4937)
-
🐛 Harden MCP server lifecycle and surface start failures in settings (#4931)
-
🐛 Isolate JmDNS lifecycle per interface and bind nearby presence to the discovery source (#4929)
-
🐛 Keep the Windows network warning dismissal across restarts (#4926)
-
🐛 Honor the discovery toggle when resolving interfaces and stop dropping hosts by last octet (#4924)
-
🐛 Bound en...
2.2.0.2544
Highlights 🌟
-
⌨️ CrossPaste CLI
Every desktop package now ships a native command-line tool,
crosspaste(macOS offers a one-click terminal command install on
first launch, and Windows offers one-click add-to-PATH). Copy with a
pipe (echo hello | crosspaste), paste, search history with the
same filters as the search window, pick entries in a full-screen
fuzzy picker, edit an entry in$EDITOR, and stream new pastes live
withwatch— plus pair devices and run the app headless on
servers, all from the terminal and your scripts. In sixel-capable
terminals, clipboard images even preview inline as real pixels. See
the
CLI guide
for every command and example (#243 #3828 #4769 #4771 #4776 #4778
#4780 #4782 #4786 #4788 #4790 #4809 #4812 #4815 #4817 #4822 #4824
#4826 #4828 #4836 #4841 #4849 #4850 #4851 #4852 #4859 #4893). -
🔐 Next-generation device pairing
Device pairing now verifies a one-time 6-digit PIN — rotating every
30 seconds on the accepting device — through a SPAKE2 (RFC 9382)
password-authenticated key exchange, so nothing on the network can
intercept the pairing or learn anything from a wrong guess, and
cumulative online PIN guesses are capped. The elliptic-curve
arithmetic runs on a constant-time OpenSSL libcrypto pinned and
bundled with the app, with a fail-closed startup probe. Devices on
older versions keep pairing through the previous flow (#4859 #4861
#4863 #4865 #4867 #4869 #4875 #4877 #4881). -
🪟 More reliable Windows clipboard capture
Rapid clipboard bursts are coalesced into one snapshot through a
single-consumer pipeline, fixing interference with Snipping Tool's
PrtScr auto-save on Windows 11; duplicate image records from a
single copy are deduplicated; and SQLite's busy timeout now takes
effect, fixing sporadic write failures under contention (#4737
#4791 #4793 #4796 #4798 #4799). -
🎨 UI improvements
The UI framework is upgraded to Compose Multiplatform 1.12, and
following the system light/dark mode is now correct from the very
first frame — no more flash at launch. The system tray now shares a
single implementation across macOS, Windows, and Linux; the main
window height is clamped to the usable screen area so the bottom of
the UI can no longer end up below the screen edge; long paste titles
clipped in the side panel show a tooltip on hover and title edits
are committed when focus moves away; and the settings font dropdown
now closes in a single click (#4759 #4761 #4885 #4886 #4887 #4901
#4902 #4903).
Bug Fixes 🐛
- 🐛 Show tooltip for clipped paste title and commit title edit on focus loss (#4903)
- 🐛 Trim surrounding whitespace when creating UrlPasteItem (#4899)
- 🐛 Stop pushing pastes to stale disconnected sync rows (#4895)
- 🐛 Drain sessions in WsSessionManager.closeAll to fix concurrent iteration flake (#4890)
- 🐛 Use origin.remoteAddress instead of remoteHost in pairing v3 routes to avoid a blocking reverse DNS lookup (#4875)
- 🐛 Read trust request bodies before taking the per-peer pairing lock (#4871 #4873)
- 🐛 Unwrap wrapped crypto failures so key mismatch surfaces as DECRYPT_FAIL (#4870 #4872)
- 🐛 Cap cumulative pairing v3 online PIN guesses and harden OpenSSL secret hygiene (#4867)
- 🐛 Map missing native graphics library to actionable 503 in CLI image route (#4857)
- 🐛 Guard cli build script host lookups on unsupported K/N hosts (#4856)
- 🐛 Survive mordant's native-Windows raw-mode timeout and restore console modes on exit (#4826)
- 🐛 Harden TaskExecutor: tolerate corrupt extraInfo, rethrow cancellation, no-throw submit after shutdown (#4806)
- 🐛 Apply sqlite pragmas via connection properties so busy_timeout takes effect (#4799)
- 🐛 Discard duplicate local image records via short-window keep-first dedup (#4798)
- 🐛 Coalesce Windows clipboard bursts into one snapshot via a single-consumer pipeline (#4796)
- 🐛 Harden the headless mode startup and shutdown paths for daemon use (#4782)
- 🐛 Give blocked CLI config keys accurate per-key hints (#4774)
- 🐛 Reject CLI config keys requiring runtime workflows (#4773)
- 🐛 Reject lossy CLI config conversions (#4772)
- 🐛 Clamp the main window height to the usable screen area (#4761)
New Features ✨
- ✨ Surface v3 PINs via crosspaste token with acceptance-window arming (#4893)
- ✨ Let clicks outside the font dropdown pass through instead of being swallowed (#4887)
- ✨ Add a redacted telemetry observer seam to PairingProtocolV3Service (#4881)
- ✨ Roll out pairing v3 by advertising PAIRING_VERSION 3 gated on the bundled backend (#4877)
- ✨ Add crosspaste token command for acceptor-side pairing code display (#4859)
- ✨ Wire sixel rendering into paste inline previews and the pick panel (#4852)
- ✨ Add sixel terminal capability probe with DA1 confirmation (#4851)
- ✨ Add raw RGBA transcode endpoint for CLI image previews (#4850)
- ✨ Add pure-Kotlin sixel encoder with median-cut quantization (#4845 #4849)
- ✨ Let a PATH-installed CLI auto-discover a dev app instance (#4843)
- ✨ One-click add-to-PATH for the Windows CLI on non-MSIX installs (#4841)
- ✨ Show the command line extension entry on every platform and in dev runs (#4836)
- ✨ Make edit update the paste in place instead of copying a new entry (#4828)
- ✨ Add a watch command streaming new pastes over an NDJSON feed (#4824)
- ✨ Add an interactive pick command with a full-screen fuzzy picker (#4822)
- ✨ Merge the search command into history with search-window-parity filters (#4817)
- ✨ Add an edit command that round-trips a paste through $EDITOR (#4815)
- ✨ Treat piped stdin to bare crosspaste as implicit copy and add c/p/h command aliases (#4812)
- ✨ Support targeting a dev app instance via CROSSPASTE_USER_DATA_DIR and a :cli:run task (#4810)
- ✨ Fit CLI list previews to the terminal width with cell-accurate truncation (#4809)
- ✨ Dump image bytes and render inline terminal previews from the CLI (#4790)
- ✨ Launch the headless daemon from the CLI and document daemon deployment (#4788)
- ✨ Pair devices from the terminal via the /cli pairing API (#4786)
- ✨ Improve the CLI terminal experience with pipes, formats, colors, and exit codes (#4780)
- ✨ Offer to install the crosspaste terminal command on macOS (#4778)
- ✨ Probe app liveness and auto-start the desktop app from the CLI (#4771)
- ✨ Serve a local /cli API over a unix domain socket and make the CLI a pure HTTP client (#4769)
Multiplatform · Refactor · Code Style 🔨
- 🔨 Unify the system tray across all three platforms on ComposeNativeTray (#4902)
- 🔨 Make TokenInputRow expect/actual so mobile can provide a flicker-free input (#4900)
- 🔨 Resolve system dark theme directly in composition via dynamic isSystemInDarkTheme (#4886)
- 🔨 Restrict production libcrypto loading to the bundled library with fail-closed startup probe (#4865)
- 🔨 Replace BouncyCastle SPAKE2 EC backend with constant-time OpenSSL via JNA (#4861)
- 🎨 Downgrade expected heartbeat decrypt-failure logs to warn without stack trace (#4838)
- 🎨 Clean up Gradle 9 deprecation warnings and Kotlin compiler warnings (#4833)
- 🔨 Derive CLI version at build time and add a cli compile gate to CI (#4767)
- 🎨 Focus the first token input box when the pairing dialog opens (#4758)
- 🎨 Auto-close the v3 pairing card when the session is cancelled (#4756)
- 🎨 Drain the v2 token countdown bar to match v3 pairing cards (#4754)
Build & CI 👷
- 👷 Auto-download the pinned libcrypto for development runs so pairing v3 loads without a system OpenSSL (#4869)
- 👷 Bundle pinned OpenSSL libcrypto into desktop packages via Conveyor (#4863)
- 👷 Bump Conveyor CLI in CI packaging workflows from v21.0 to v22.1 (#4839)
- 👷 Split the CLI native build into a parallel path-gated CI job (#4803)
- 👷 Tier the test suite so PRs run fast tests and releases run integration suites (#4801)
- 👷 Suppress expected Kotlin/Native disabled-target and cinterop commonization warnings (#4784)
- 👷 Ship the CLI binary in all desktop packages (#4776)
- ✅ Add an --advertise-address option to the e2e harness (#4752)
Dependencies ⬆️
- ⬆️ Bump ComposeNativeTray from 1.3.3 to 2.1.3 for Compose 1.12 support (#4901)
- ⬆️ Bump io.coil-kt.coil3 from 3.5.0 to 3.6.0 for Compose 1.12 support and GIF/AsyncImage rendering fixes
- ⬆️ Bump com.mohamedrejeb.richeditor:richeditor-compose from 1.0.0 to 1.1.0 for Compose 1.12 support and a clipboard fix (#4891)
- ⬆️ Bump gradle-wrapper from 9.7.0 to 9.7.1 (#4889)
- ⬆️ Upgrade Compose Multiplatform to 1.12.0 (#4885)
- ⬆️ Bump io.github.vinceglb:filekit-dialogs from 0.14.2 to 0.15.0 (#4819)
- ⬆️ Bump ch.qos.logback:logback-classic from 1.6.1 to 1.6.3 (#4818)
- ⬆️ Bump org.bouncycastle:bcprov-jdk18on from 1.85 to 1.85.2 (#4765)
- ⬆️ Bump org.jetbrains.compose.hot-reload from 1.1.1 to 1.2.0 (#4764)
- ⬆️ Bump gradle-wrapper from 9.6.1 to 9.7.0 (#4763)
- ⬆️ Bump postcss to 8.5.26 to fix source map disclosure advisories (#4762)
2.1.7.2461
Highlights 🌟
-
🛡️ Hardened device sync
A full round of security and robustness hardening on the sync path:
sync connections and control requests strictly verify peer identity,
file transfers validate path legitimacy and cap resource usage, and
malformed data can no longer disrupt normal syncing (#4705–#4716). -
🔗 More reliable connections
A corrupted device record no longer prevents the device list from
loading; metadata read failures no longer reset the device identity;
device state changes propagate reliably across the UI; devices now
show as connected the moment an incoming connection is established,
instead of waiting for the next liveness poll; and HarmonyOS
devices are recognized with their own icon (#4695 #4720 #4722 #4724
#4728 #4747). -
🚀 The main window now opens on first launch
Fixed an issue on some platforms where the first launch only showed a
tray icon and no window at all, making it look like the app "wouldn't
open". The main window now opens automatically on first launch on
every desktop platform (#4696 #4697). -
🗄️ Customizable size limit for large clipboard entries
A new setting customizes the maximum size for text, HTML, rich text,
and link content written into the history (8MB by default). Entries
over the limit are not recorded, so meaninglessly huge text can't
bloat the database or slow down the UI; sync skips them too, without
breaking pull continuity. Files and images are not affected
(#4699 #4701 #4703 #4704). -
🎨 New Appearance settings page
Settings now has an Appearance page with a customizable side search
window height and live preview. Card title bars in the side window
scale proportionally with card size (#4664 #4674 #4676). -
🍎 macOS: hide the Dock icon
A new macOS-only setting hides CrossPaste from the Dock, keeping only
the menu bar icon (#4659 #4677 #4678). -
🔒 URL preview fetching can now be turned off
A new setting disables fetching a copied link's title and icon, so
CrossPaste makes no network request for copied URLs — for privacy,
or to avoid accidentally triggering one-time links. On by default,
matching the previous behavior (#4742 #4744). -
🧩 Chrome extension improvements
The extension now decrypts encrypted paste pushes from the desktop
app, supports the newer SAS/PIN-based pairing flows, and performs
the authenticated WebSocket handshake so it can keep syncing with
peers that require authenticated connections (#4683 #4729 #4730
#4749).
Bug Fixes 🐛
- 🐛 Implement authenticated WebSocket handshake in the Chrome extension (#4749)
- 🐛 Resolve device state immediately when an inbound WebSocket session opens (#4747)
- 🐛 Dedupe search results by id in the shared search ViewModel (#4733)
- 🐛 Decrypt encrypted WS paste push in Chrome extension (#4730)
- 🐛 Tolerate corrupted hostInfo JSON per row in device-list mapping (#4728)
- 🐛 Never rotate device identity on metadata read failure (#4724)
- 🐛 Give SyncRuntimeInfo flow broadcast semantics (#4722)
- 🐛 Include network prefix in host info equality (#4720)
- 🐛 Make ErrorCode hashCode consistent with equals (#4718)
- 🐛 Validate file transfer path metadata correspondence (#4716)
- 🐛 Roll back push prepare on session capacity rejection (#4714)
- 🐛 Authenticate sync control requests (#4712)
- 🐛 Disambiguate WebSocket whole-file pulls (#4711)
- 🐛 Authenticate WebSocket sessions (#4710)
- 🐛 Bind WebSocket paste identity (#4709)
- 🐛 Bound remote file transfer resources (#4708)
- 🐛 Fail truncated file chunks (#4707)
- 🐛 Bind remote paste to authenticated identity (#4706)
- 🐛 Reject unsafe remote file paths (#4705)
- 🐛 Prevent paste pull cursor gaps (#4704)
- 🐛 Persist paste pull cursor for discarded oversized remote pastes (#4703)
- 🐛 Auto-show main window on first launch for all desktop platforms (#4697)
- 🐛 Allocate v2 exchange generations before async dispatch and make verifier acquisition atomic (#4693)
- 🐛 Release the responder's pending v2 exchange when the initiator abandons pairing (#4690)
- 🐛 Fix SPAKE2 session lifecycle races and fail closed pending constant-time EC review (#4663)
New Features ✨
- ✨ Add option to disable URL preview fetching (#4744)
- ✨ Add chunked WebSocket payload transfer negotiated via the pairing v3 handshake (dormant until v3 rollout) (#4732)
- ✨ Discard oversized non-file paste items to prevent huge database rows (#4699)
- ✨ Add HarmonyOS platform support with system icon (#4695)
- ✨ Add pairing v2 (SAS) and v3 (SPAKE2 PIN) support to the browser extension (#4683)
- ✨ Render pairing v3 acceptor sessions as per-device token cards with auto-close on trust (#4681)
- ✨ Add macOS setting to hide the Dock icon (#4677)
- ✨ Add appearance settings page with customizable search window height (#4674)
- ✨ Add development-only pairing v3 interop flag (#4667)
- ✨ Add pairing v3 scenarios (pair-v3, all-v3) to e2e harness (#4665)
- ✨ Pairing v3: real SPAKE2/P-256 PakeProvider with RFC 9382 vectors (#4658)
- ✨ Pairing v3 Phase 4: desktop UI (#4656)
- ✨ Pairing v3 Phase 3: network protocol service, routing, and client API (#4654)
- ✨ Pairing v3 foundation: per-device sessions, PIN + SPAKE2 building blocks (#4652)
Multiplatform · Refactor · Code Style 🔨
- 🔨 Scale side paste title bar proportionally with card size (#4676)
- 🔨 Harden pairing v3 interop handshake and trust dialog UX (#4669)
- 🔨 Extract PairingV3Transport seam for in-process pairing v3 tests (#4661)
- 🔨 Split stored paste JSON codec from sync format and fix hashing and size accounting (#4648)
- 🔨 Separate QR bearer token from SAS code at the type level (#4644)
- 🔨 Harden paste process plugin pipeline and cap max non-file paste size input (#4701)
Build & CI 👷
- 👷 Add Microsoft Store publish automation (#4738)
- 👷 Speed up CI with per-job Gradle caches, konan cache, and superseded-run cancellation (#4689)
- ✅ Move platform-agnostic tests to core commonTest and cover core/shared in CI (#4646)
Documentation 📝
- 📝 Replace contact email with support@crosspaste.com (#4671)
- 📝 Add Video link to README navigation
- 📝 Bump README download badge to v2.1.6
Dependencies ⬆️
- ⬆️ Bump org.bouncycastle:bcprov-jdk18on from 1.84 to 1.85 (#4741)
- ⬆️ Bump com.squareup.okio:okio from 3.18.0 to 3.18.1 (#4740)
- ⬆️ Bump ktor from 3.5.1 to 3.5.2 (#4739)
- ➖ Drop unused Compose plugin and runtime from shared (#4726)
- ⬆️ Bump logback-classic from 1.5.38 to 1.6.1 (#4687)
- ⬆️ Bump io.modelcontextprotocol:kotlin-sdk-server (#4686)
- ⬆️ Bump kotter from 1.3.0 to 1.4.0 (#4685)
- ⬆️ Bump metadata-extractor from 2.20.0 to 2.21.0 (#4650)
- ⬆️ Bump okio from 3.17.0 to 3.18.0 (#4649)
- ⬆️ Bump compose-shimmer (#4642)
- ⬆️ Bump richeditor-compose
- ⬆️ Bump kotlin from 2.4.0 to 2.4.10
- ⬆️ Bump imageio from 3.13.1 to 3.14.0
2.1.6.2390
Highlights 🌟
-
🔁 Fixed a clipboard loop between the Chrome extension and desktop
Running the Chrome extension and the desktop app on the same machine
could bounce the same clipboard entry back and forth endlessly,
flooding the history with duplicates. Both sides now recognize
content written by the other and no longer re-trigger each other
(#4619 #4620). -
🪟 Same-machine pause protection now actually works on Windows
The native messaging bridge that lets the extension detect a running
desktop app never launched on Windows: the host manifest pointed to
the bridge script with a forward-slash path, which cmd.exe — used by
Chromium to launch non-exe hosts — cannot execute. The manifest now
keeps native backslashes, the bridge script resolves the pid file at
run time (immune to code-page path garbling on non-ASCII user
profiles), and stdin draining is Windows PowerShell 5.1-safe. While
the desktop app is running, the extension on the same machine now
pauses its clipboard capture as designed (#4633 #4634). -
🪟 Upgraded clipboard monitoring on Windows
Clipboard monitoring on Windows now uses the AddClipboardFormatListener
event mechanism, so copied content is picked up faster and more
reliably. The "copied from" app is now resolved via GetClipboardOwner
— the program that actually wrote to the clipboard — instead of
whichever window happened to be in the foreground (#4597 #4606). -
🪟 Works on newer Windows builds without wmic
Newer Windows 11 builds have removed the wmic tool, which prevented
CrossPaste from generating a device identifier. It now reads the
registry MachineGuid instead (#4580). -
🧩 Extension zip from GitHub Releases now connects to the desktop app
Loading the Chrome extension zip via "Load unpacked" used to fail with
"Access to the specified native messaging host is forbidden", because
Chrome assigned it a different extension ID on every machine. The
extension ID is now pinned to the Chrome Web Store ID, so unpacked
installs connect to the desktop app just like the store version
(#4631 #4632). -
🔍 Search window resets properly on reopen
Reopening the search window or changing the query now scrolls the
list back to the top and selects the newest entry, instead of keeping
a stale position or selection (#4595 #4600). -
📶 Device discovery prefers your LAN
When a computer has multiple network connections (such as a cellular
modem or a phone hotspot), CrossPaste now ranks local network
interfaces first when discovering nearby devices (#4568). -
🐧 New Linux ARM64 build
CrossPaste now ships a Linux ARM64 (aarch64) package, so ARM-based
Linux devices are supported too (#4581 #4582 #4626).
Bug Fixes 🐛
- 🐛 Keep native backslashes in the native messaging host path so cmd.exe can launch the bridge script, resolve the pid file via %~dp0, and make the stdin drain PowerShell 5.1-safe (#4634)
- 🐛 Read lastError on native host disconnect to log the reason and silence unchecked-error noise (#4634)
- 🐛 Pin Chrome extension ID via manifest key so unpacked installs can reach the native messaging host (#4632)
- 🐛 Build Linux ARM64 in releases and survive the apt-repo site layout (#4626)
- 🐛 Fix endless clipboard duplication loop between Chrome extension and desktop (#4620)
- 🐛 Force PNG output for README avatars to keep circle-mask corners transparent (#4615)
- 🐛 Migrate Windows clipboard monitoring to AddClipboardFormatListener (#4606)
- 🐛 Reset side search selection and scroll to newest on reopen and query change (#4600)
- 🐛 Resolve Windows clipboard source via GetClipboardOwner instead of foreground window (#4597)
- 🐛 Pass signing_key to Conveyor in the Linux beta workflow (#4584)
- 🐛 Replace deprecated wmic with registry MachineGuid for Windows device UUID (#4580)
- 🐛 Lower WindowsProcessUtils version-resource log from error to debug (#4578)
- 🐛 Capture network errors in ResourcesClient.request() instead of throwing (#4577)
- 🐛 Rank LAN interfaces above cellular for device discovery (#4568)
New Features ✨
Performance ⚡
- ⚡ Use plain remember for RichTextState in side preview views (#4618)
Multiplatform · Refactor · Code Style 🔨
- 🔨 Remove runBlocking from DesktopAppLaunchState DI assembly (#4575)
- 🔨 Group Koin module declarations by sub-domain with regions (#4573)
- 🔨 Make ImageHandler and ImageWriter I/O methods suspend (#4570)
Build & CI 👷
- 👷 Decouple update-site publishing from release builds (#4630)
- 👷 Drop the nested apt repo from versioned release assets (#4627)
- 👷 Replace contrib.rocks with manually triggered contributors README workflow (#4613)
- 👷 Add manual Linux beta build workflow (#4583)
- 👷 Serve updates from the OSS-backed CDN site (#4560)
- 👷 Mirror the Conveyor update site to a stable OSS prefix (#4559)
Documentation 📝
- 📝 Fix checkered flag emoji code in commit guide (#4598)
Dependencies ⬆️
- ⬆️ Gradle Wrapper 9.5.1 → 9.6.1 (#4589 #4608)
- ⬆️ logback-classic 1.5.34 → 1.5.37 (#4592 #4611)
- ⬆️ MCP Kotlin SDK Server 0.13.0 → 0.14.0 (#4628)
- ⬆️ Ktor 3.5.0 → 3.5.1 (#4607)
- ⬆️ web build deps vite / @babel/core security bump (#4593)
- ⬆️ composenativetray-jvm bump (#4591)
- ⬆️ webp-imageio 0.10.2 → 0.11.0 (#4588)
- ⬆️ Koin 4.2.1 → 4.2.2 (#4585)
- ⬆️ Coil 3.4.0 → 3.5.0 (#4566)
- ⬆️ filekit-dialogs 0.14.1 → 0.14.2 (#4565)
- ⬆️ HikariCP 7.0.2 → 7.1.0 (#4564)
- ⬆️ JNA 5.19.0 → 5.19.1 (#4563)
New Contributors 👋
- @swording-k made their first contribution in #4598
Full Changelog: 2.1.5.2343...2.1.6.2390
CrossPaste Linux Beta (build 2360)
Linux beta (amd64+aarch64) for #4581 ARM testing. Unsigned packages — do not use the in-app auto-updater.
2.1.5.2343
Highlights 🌟
This is an urgent hotfix release with a single purpose. We recommend all users upgrade.
- 🛠️ Fixed "Check for Updates" failing with an error
Clicking Check for Updates while a newer version was available threw
"Cannot call invokeAndWait from the event dispatcher thread" and the
update flow stopped there. This affected the Windows installer and
macOS builds; the Microsoft Store and Windows portable zip channels
were not affected (#4554).
Bug Fixes 🐛
- 🐛 Guard update-check trigger against invokeAndWait on the EDT (#4555)
Full Changelog: 2.1.4.2340...2.1.5.2343
2.1.4.2340
Highlights 🌟
-
🔄 Faster, more reliable reconnection
This release focuses on the connection between your devices. When you
switch Wi-Fi networks, your network address changes, or your computer
wakes from sleep, CrossPaste now rediscovers your other devices and
reconnects much faster — no more being stuck "offline" for a long
time. Even when a device's IP address changes, it reconnects reliably
(#4506 #4510 #4515 #4519 #4521 #4527 #4529). -
🆕 In-app changelog and upgrade reminder
You can now see what each update brings right inside the app. When a
new version is available, a small dot appears in the left menu to
remind you to upgrade (#4525). -
⬆️ Windows (portable zip): update from within the app
The Windows portable (zip) build can now update itself. When a new
version is available, CrossPaste downloads and verifies it, then swaps
in the new build and restarts — no more manually downloading and
extracting a fresh zip (#4537). -
🖱️ Fixed an endless paste loop
Fixed an issue where pressing Cmd/Ctrl+V could trigger an endless
paste loop in some situations. Pasting is now more reliable (#4501
#4502). -
✨ Smoother device list
The device list no longer flickers while re-checking offline devices,
so it stays steady (#4508).
Bug Fixes 🐛
- 🐛 Gate
/sync/telnetaddress-push to already-paired peers (#4529) - 🐛 Harden network discovery: non-blocking mDNS teardown, debounced rebuild, offline gate (#4515)
- 🐛 Stop device list flicker when re-probing offline devices (#4508)
- 🐛 Decouple device identity from IP for reliable reconnection (#4506)
- 🐛 Suppress shortcut recognition during simulated paste (#4502)
- 🐛 Stop swallowing CancellationException in sync resolve loop (#4504)
- 🐛 Prevent infinite paste loop from Cmd+V shortcut binding (#4501)
- 🐛 Round drag preview corners on web paste cards (#4485)
- 🐛 Fix CLI native build after
appInstanceIdmoved out ofAppConfig(#4482)
New Features ✨
- ✨ In-app self-update for the Windows portable-zip distribution (#4537)
- ✨ Discovery-driven fast reconnect for paired peers (#4527)
- ✨ In-app What's New changelog screen with upgrade badge (#4525)
- ✨ Push subnet-matched address on steady-state heartbeat (#4521)
- ✨ Push subnet-matched address on
/sync/telnetto cut mDNS reconnection latency (#4519) - ✨ Self-heal mDNS discovery on OS network changes (#4510)
Multiplatform · Refactor · Code Style 🔨
- 🔨 Remove Jewel dependency in favor of native Compose Window (#4489)
- 🎨 Reduce SyncResolver connection-polling log noise (#4523)
Build & CI 👷
- 👷 Regenerate web version and translation artifacts (#4487)
- 👷 Upgrade GitHub Actions to Node.js 24 runtime (#4480)
Documentation 📝
- 📝 Default to Chinese for developer interaction in CLAUDE.md (#4512)
Dependencies ⬆️
- ⬆️ composenativetray-jvm bump (#4535)
- ⬆️ logback-classic 1.5.32 → 1.5.34 (#4497 #4534)
- ⬆️ web build deps rollup / postcss security bump (#4533)
- ⬆️ Kotlin 2.3.21 → 2.4.0 (#4513)
- ⬆️ Compose Multiplatform 1.11.0 → 1.11.1 (#4511)
- ⬆️ MCP Kotlin SDK Server bump (#4517)
- ⬆️ JNA 5.18.1 → 5.19.0 (#4516)
- ⬆️ ph-css 8.1.1 → 8.2.1 (#4498)
- ⬆️ Gradle Wrapper 9.5.0 → 9.5.1 (#4491)
- ⬆️ kotlin-logging 8.0.03 → 8.0.4 (#4492)
- ⬆️ MockK 1.14.9 → 1.14.11 (#4493)
- ⬆️ Caffeine bump (#4494)
- ⬆️ atomicfu 0.32.1 → 0.33.0 (#4495)
Full Changelog: 2.1.3.2297...2.1.4.2340
2.1.3.2297
Highlights 🌟
-
📤 Faster file sharing across devices
Sharing files between your devices is now snappier and more reliable.
The device you copied from delivers files directly to your other
devices, instead of making them ask for the data first. This also
paves the way for the upcoming iOS Share Extension, letting you share
files straight from any app on your iPhone or iPad to your desktop
(#4456 #4457 #4467 #4468). -
🛡️ Windows: heads-up when your network blocks CrossPaste
On Windows, if your network is set to "Public", the Windows Firewall
silently blocks CrossPaste from finding nearby devices. CrossPaste
now detects this and offers a one-click shortcut to the Windows
setting where you can switch the network to Private (#4402 #4404). -
🖱️ Smoother drag-and-drop from CrossPaste
Dragging items from the CrossPaste side panel into other apps is
now much better. On macOS, the drag preview no longer hides behind
the paste window — you can finally see what you're dragging. The
side panel also handles edge cases more gracefully, so drags don't
get blocked while previews are still loading, and dragging stays
smooth even with lots of items on screen. Bonus: you can now drag
to reorder your search tags too (#4361 #4357 #4377 #4388). -
🖼️ Animated GIFs and real video thumbnails in the side preview
GIFs in your clipboard history now actually animate (smoothly, even
for large ones), and video files show a real thumbnail of the first
frame in the side panel instead of a generic icon. We also fixed a
rare crash that could happen while previews were loading (#4353 #4410
#4422 #4438).
Bug Fixes 🐛
- 🐛 Pre-allocate file slots on push receive so the first chunk has somewhere to land (#4468)
- 🐛 Namespace nearby device LazyColumn keys to avoid a Compose 1.11 duplicate-key crash (#4470)
- 🐛 Bypass JVM system proxy for LAN sync traffic so peer sync no longer hangs behind a configured HTTP proxy (#4449)
- 🐛 Make smoke-test orphan-JVM kill order-independent so cleanup keeps working if the launcher reorders
-Dflags (#4452) - 🐛 Replace
dzirbel/compose-material-context-menu(incompatible with Compose 1.11TextContextMenuAPI) with an in-tree Material context menu to fix text-field crash (#4448) - 🐛 Stop smoke-test from killing user's PROD CrossPaste and aborting on macOS bash 3.2 (#4445)
- 🐛 Serialize Skia codec/bitmap close with in-flight readPixels (#4438)
- 🐛 Bring main window to front on every showMainWindow call (#4408)
- 🐛 Fix COM ref leak and false-positive warning in Windows network detection (#4404)
- 🐛 Composite translucent HTML/RTF preview bg over theme to avoid double-blending (#4400)
- 🐛 Sort nvm node versions by parsed semver in web build (#4390)
- 🐛 Reset selected index when the search window opens (#4382)
- 🐛 Stop surfacing CancellationException as a refresh failure (#4373)
- 🐛 Stop ClientEncryptPlugin throwing on bodyless GET and harden pull error handling (#4371)
- 🐛 Harden thumbnail extraction and fix .ts TypeScript misclassification (#4367)
- 🐛 Resolve npm absolute path in :web build to fix daemon Exec error 2 (#4365)
- 🐛 Lower mac paste window level so drag preview is visible (#4361)
- 🐛 Skip empty Apple sync tasks and harden side drag preview (#4357)
- 🐛 Skip iPhone/iPad peers for Apple Universal Clipboard pastes (#4355)
- 🐛 Accept
java.net.URLtransfer data inDesktopUrlTypePlugin(#4349) - 🐛 Fix side search crashes on fast horizontal scroll (#4347)
- 🐛 Route Apple Universal Clipboard pastes to non-Mac peers (#4344)
- 🐛 Correct
.gitignoreentry toscheduled_tasks.lock
New Features ✨
- ✨ Add desktop file push protocol —
/sync/pastepush mode +/sync/file/push+/sync/paste/push/complete(M1+M2) (#4456) - ✨ Add desktop-side client for the file push protocol (M4) (#4457)
- ✨ Redesign OCR language rows and add drag-to-reorder for loaded languages (#4473)
- ✨ Add
PasteDao.filterExistingIdsfor stale-id filtering (#4428) - ✨ Add bulk tag operations to
PasteTagDao(#4426) - ✨ Animate GIFs in image side preview via Skia codec (#4410)
- ✨ Add
UserAttentionServiceto gate background pollers on window visibility (#4406) - ✨ Detect Windows Public network profile and offer one-click jump to settings (#4402)
- ✨ Add drag-and-drop reordering for search tags (#4377)
- ✨ Add Chrome extension release tooling and marketing preview (#4363)
- ✨ Preview video files in side panel with native thumbnails (#4353)
- ✨ Make device info values selectable for copy (#4320)
UI Improvements 💄
- 🎨 Simplify settings description copy across all locales (#4315)
Multiplatform · Refactor · Code Style 🔨
- 🔨 Extract push out of
SyncPasteTaskExecutorintoSharePushOrchestrator(#4467) - 🔨 Extract
DesktopBootstrapto consolidate process-wide hooks (#4450) - 🔨 Opt in to
ExperimentalRichTextApiin HTML/RTF side previews (#4424) - 🔨 Catch block exceptions inside
launchWhileAttentiveso a single failed tick doesn't kill the poller (#4415) - 🔨 Regenerate
web/package-lock.jsonandi18n/translations.generated.ts(#4386) - 🔨 Lazy-resolve npm in
:webGradle config, drop interactive-shell probe (#4384) - 🔨 Consolidate
MacAcrylicEffectand tidy small readability issues (#4369) - 🔨 Extract
hbitmapToBufferedImageand addPlatform.isApple(#4359) - 🔨 Introduce
PasteSourceContextto bundle paste origin metadata (#4342) - 🔨 Use
Durationform forkotlinx.coroutines.delaycalls (#4340) - 🔨 Extract
AbstractGlobalCopywritertocommonMain(#4338) - 🔨 Hoist shared i18n primitives to
commonMain(#4336) - 🔨 Clarify
DiscoveryDriver.browsecontract and makeTargetCacheatomic (#4334) - 🔨 Harden
DiscoveryDriver.close()and useDateUtilsin e2e (#4332) - 🔨
:e2eharness review follow-ups (#4329) - 🔨 Harden
appInstanceIdloadOrCreateand surfaceOneFilePersistwrite failures (#4322) - 🔨 Harden
appInstanceIdmigration against corrupt metadata (#4317) - 🔨 Extract
appInstanceIdout ofAppConfig(#4313) - 🔨 Lazy-init
deviceId/deviceNameinEndpointInfoFactory(#4311)
Performance ⚡
- ⚡ Decode GIF frames off the UI thread with double buffering (#4422)
- ⚡ Defer
dragOffsetXread to layer phase inSearchTagsView(#4388) - ⚡ Stop firing side search load-more on every scroll frame (#4351)
Testing ✅
- ✅ Regression tests for
MaterialContextMenuhover-index and submenu position (#4454) - ✅ Regression test for
SkiaAnimatedImageViewclose ordering (#4444) - ✅ Add
:e2ereal-device test harness (#4318)
Build & CI 👷
- 👷 Auto-update GitHub Sponsors avatars in README, with historical sponsors and rounded avatar rendering (#4458 #4462 #4464)
- 👷 Add desktop startup smoke test to CI (#4442)
- 👷 Drop
/hyperframes-demo/from.gitignore(#4412) - 👷 Ignore
/.claude/worktrees/ - 👷 Ignore
scheduled_task.lockandskills-lock.json - 👷 Ignore
/hyperframes-demo/directory - 👷 Ignore
/.dev-context/directory (#4309)
Documentation 📝
- 📝 Require English for GitHub issue and PR content
- 📝 Refresh README, CHANGELOG and Roadmap for v2.0.0 release (#4327)
Dependencies ⬆️
- ⬆️ kotlinx-coroutines 1.10.2 → 1.11.0 (#4474)
- ⬆️ kotlinx-serialization-json bump (#4475)
- ⬆️ kotlin-logging 8.0.02 → 8.0.03 (#4477)
- ⬆️ kotter 1.2.1 → 1.3.0 (#4478)
- ⬆️ Compose Multiplatform → 1.11.0 (#4417)
- ⬆️ Ktor 3.4.2 → 3.5.0 (#4305 #4429)
- ⬆️ Kotlin 2.3.20 → 2.3.21 (#4324)
- ⬆️ Jewel 0.34.0-253 → 0.36.0-261 (#4307 #4432 #4434)
- ⬆️ Compose Shimmer → 1.5.0-beta02 (#4325 #4436)
- ⬆️ richeditor-compose → 1.0.0-rc14 (#4419)
- ⬆️ filekit-dialogs 0.13.0 → 0.14.1 (#4430)
- ⬆️ Gradle Wrapper 9.4.0 → 9.5.0 (#4394)
- ⬆️ atomicfu 0.31.0 → 0.32.1 (#4391)
- ⬆️ kotlin-logging 8.0.01 → 8.0.02 (#4392)
- ⬆️ kotlinx-datetime bump (#4393)
- ⬆️ MCP Kotlin SDK Server bump (#4431)
- ⬆️ semver 3.0.0 → 3.1.0 (#4379)
- ⬆️ compose.hot-reload bump (#4378)
- ⬆️ ksoup 0.2.5 → 0.2.6 (#4380)
- ⬆️ icu4j 78.2 → 78.3 (#4308)
- ⬆️ metadata-extractor 2.19.0 → 2.20.0 (#4323)
Full Changelog: 2.0.0.2192...2.1.3.2297