Skip to content

Releases

2.3.1.2781

Choose a tag to compare

@guiyanakuang guiyanakuang released this 30 Oct 11:42
0565512

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 for bin\CrossPaste.exe on 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

Choose a tag to compare

@guiyanakuang guiyanakuang released this 24 Oct 10:21
6fe2c3c

Highlights 🌟

  • 🧩 Local process plugins in the paste context menu
    A plugin is a folder with a manifest.json and 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).

  • ⌨️ crosspaste is the CLI on Windows installs
    Installer and Microsoft Store packages register both crosspaste and
    crosspaste-cli as 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 crosspaste launch 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 👋

Full Changelog: 2.2.1.2706...2.3.0.2767

2.2.1.2706

Choose a tag to compare

@guiyanakuang guiyanakuang released this 11 Oct 03:36
59a14b5

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...

Read more

2.2.0.2544

Choose a tag to compare

@guiyanakuang guiyanakuang released this 01 Sep 05:08

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
    with watch — 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

Choose a tag to compare

@guiyanakuang guiyanakuang released this 10 Aug 02:06
8ec3b77

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

Choose a tag to compare

@guiyanakuang guiyanakuang released this 14 Jul 07:09

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 ✨

  • ✨ Add Linux aarch64 (ARM64) build target (#4582)
  • ✨ Add telnet scenario to e2e harness (#4562)

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 👋

Full Changelog: 2.1.5.2343...2.1.6.2390

CrossPaste Linux Beta (build 2360)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 20 Jun 05:47
724c975

Linux beta (amd64+aarch64) for #4581 ARM testing. Unsigned packages — do not use the in-app auto-updater.

2.1.5.2343

Choose a tag to compare

@guiyanakuang guiyanakuang released this 11 Jun 05:35
64d44d0

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

Choose a tag to compare

@guiyanakuang guiyanakuang released this 10 Jun 14:13
63be907

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/telnet address-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 appInstanceId moved out of AppConfig (#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/telnet to 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

Choose a tag to compare

@guiyanakuang guiyanakuang released this 27 May 03:09

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 -D flags (#4452)
  • 🐛 Replace dzirbel/compose-material-context-menu (incompatible with Compose 1.11 TextContextMenu API) 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.URL transfer data in DesktopUrlTypePlugin (#4349)
  • 🐛 Fix side search crashes on fast horizontal scroll (#4347)
  • 🐛 Route Apple Universal Clipboard pastes to non-Mac peers (#4344)
  • 🐛 Correct .gitignore entry to scheduled_tasks.lock

New Features ✨

  • ✨ Add desktop file push protocol — /sync/paste push 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.filterExistingIds for stale-id filtering (#4428)
  • ✨ Add bulk tag operations to PasteTagDao (#4426)
  • ✨ Animate GIFs in image side preview via Skia codec (#4410)
  • ✨ Add UserAttentionService to 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 SyncPasteTaskExecutor into SharePushOrchestrator (#4467)
  • 🔨 Extract DesktopBootstrap to consolidate process-wide hooks (#4450)
  • 🔨 Opt in to ExperimentalRichTextApi in HTML/RTF side previews (#4424)
  • 🔨 Catch block exceptions inside launchWhileAttentive so a single failed tick doesn't kill the poller (#4415)
  • 🔨 Regenerate web/package-lock.json and i18n/translations.generated.ts (#4386)
  • 🔨 Lazy-resolve npm in :web Gradle config, drop interactive-shell probe (#4384)
  • 🔨 Consolidate MacAcrylicEffect and tidy small readability issues (#4369)
  • 🔨 Extract hbitmapToBufferedImage and add Platform.isApple (#4359)
  • 🔨 Introduce PasteSourceContext to bundle paste origin metadata (#4342)
  • 🔨 Use Duration form for kotlinx.coroutines.delay calls (#4340)
  • 🔨 Extract AbstractGlobalCopywriter to commonMain (#4338)
  • 🔨 Hoist shared i18n primitives to commonMain (#4336)
  • 🔨 Clarify DiscoveryDriver.browse contract and make TargetCache atomic (#4334)
  • 🔨 Harden DiscoveryDriver.close() and use DateUtils in e2e (#4332)
  • 🔨 :e2e harness review follow-ups (#4329)
  • 🔨 Harden appInstanceId loadOrCreate and surface OneFilePersist write failures (#4322)
  • 🔨 Harden appInstanceId migration against corrupt metadata (#4317)
  • 🔨 Extract appInstanceId out of AppConfig (#4313)
  • 🔨 Lazy-init deviceId / deviceName in EndpointInfoFactory (#4311)

Performance ⚡

  • ⚡ Decode GIF frames off the UI thread with double buffering (#4422)
  • ⚡ Defer dragOffsetX read to layer phase in SearchTagsView (#4388)
  • ⚡ Stop firing side search load-more on every scroll frame (#4351)

Testing ✅

  • ✅ Regression tests for MaterialContextMenu hover-index and submenu position (#4454)
  • ✅ Regression test for SkiaAnimatedImageView close ordering (#4444)
  • ✅ Add :e2e real-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.lock and skills-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