Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Releases: ShunmeiCho/cc-clip

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 29 Aug 06:16
98f2add

What's New in v0.11.0

Copying out of a remote session now works without you asking it to, Windows paste works in the terminals where it silently did nothing, and Cursor finally tells you when it is done.

Copy on the remote, paste on your machine — no command to remember

v0.10.0 gave you cc-clip copy as an explicit pipe. That was the wrong shape: copying in a remote session does not happen through pipes. You yank in neovim, you hit Enter in tmux copy-mode, you use a TUI's copy action — and all of those invoke xclip or wl-copy, which the shim already sits in front of.

So it now just happens:

" in neovim on the remote
set clipboard=unnamedplus     " y / yy / p now cross the SSH boundary
# in tmux on the remote
set -g set-clipboard off
bind -T copy-mode-vi Enter send -X copy-pipe-and-cancel 'xclip -selection clipboard -i'

The write is forwarded through the tunnel to your local clipboard and replayed into the remote's real xclip, so the remote clipboard behaves exactly as before. Either side succeeding is enough — headless remotes with no real xclip still work. Bytes are verbatim: no terminal rendering is involved, so nothing is soft-wrapped or mangled.

cc-clip copy remains the explicit primitive for pipes. docs/reverse-copy.md covers both configurations and states the boundary honestly: a mouse selection in your local terminal copies what the terminal rendered, no SSH-side process observes it, and no version of cc-clip changes that.

Windows: the paste that reported success and did nothing (#140)

On Electron-based terminals — Wave, Hyper, Tabby, VS Code's integrated terminal — the auto-paste was silently dropped. The upload landed, hotkey.log said send completed, the tray said Image pasted to <host>, the focus guard logged no abort, and the terminal received nothing at all. The keystroke went out through WinForms SendKeys, which Chromium windows ignore outright while SendWait still returns success.

The keystroke is now delivered with SendInput, which those terminals accept, and which reports how many events the input stream actually took — so a refusal (a window running as administrator, for instance) is an error instead of a silent success. It also releases a physically-held ALT/WIN first, so the modifiers of the triggering hotkey no longer merge into the chord.

Two more fixes on the same path:

cc-clip hotkey myserver --no-restore

--no-restore was available on send --paste but not on hotkey. It leaves the remote path on the clipboard instead of putting the image back 150 ms later, so on any terminal that still drops synthetic input your own Ctrl+V pastes the right thing. It persists as "no_restore": true in hotkey.json, so it survives the autostart launcher and a reboot.

And cc-clip hotkey --status no longer reports "not running" for a loop that is plainly alive. It identified the process by asking PowerShell for Win32_Process.CommandLine and treated every failure of that lookup — including the empty result you get without rights to read it — as "not our process", then deleted the PID file. One unreadable reading lost the PID permanently: --status said "not running" forever afterwards and --stop could no longer stop the process. Identity now comes from the process image path, and the probe distinguishes gone / not ours / could not tell, reporting the third instead of claiming the loop is down.

Thanks to @Song100Years for a report that diagnosed all three correctly, including the detail that SendWait returns success regardless — which is what made the first one findable at all.

Cursor CLI notifications (#109)

cc-clip connect myserver --cursor

--cursor shipped clipboard support in v0.10.0; it now installs a notify hook too, merged into ~/.cursor/hooks.json. Your own hooks in that file are preserved — the stop event keeps every command that is not ours, and a file that will not parse is refused rather than overwritten.

cc-clip doctor covers the notification bridge (#22)

doctor previously stopped at the clipboard path. It now checks the notify nonce, the hook wiring, and the delivery chain, so "notifications stopped working" is a diagnosable state rather than a guess.

Other Improvements

  • Windows is now built and tested in CI. checks.yml ran only on ubuntu-latest, which compiles none of the //go:build windows files — the hotkey loop, the tray, every clipboard writer and all of their tests were invisible to every gate, and a break surfaced only when goreleaser cross-compiled at tag time. That is the actual reason the three bugs above shipped. There is now a cross-build + vet step for windows/darwin on both arches, a windows-latest test job, and a gofmt gate.
  • staticcheck is pinned. It was invoked as @latest against a pinned toolchain; when staticcheck raised its own Go floor, CI went red on commits that had changed nothing.
  • main.go split into connect.go / notify.go / serve.go (#20).
  • Docs: docs/reverse-copy.md is new; docs/commands.md gains the --cursor row it never had; the zh/ja READMEs mirror the v0.10.0 feature set.
  • The daemon no longer prefixes its own clipboard-write notification with [unverified]. That marker means "this text came from somewhere the daemon cannot vouch for"; spending it on a message the daemon wrote itself is how it stops meaning anything.

Upgrade

Local machine first, then each remote host.

# macOS / Linux, existing install
cc-clip update

# macOS / Linux, fresh install
curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | bash
# Windows, install or upgrade
irm https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.ps1 | iex

Then, for every remote host:

cc-clip connect <host> --force

The reverse-copy write shim and the Cursor notify hook are both installed by connect; without this step the remote keeps the old shim and nothing above changes for that host.

Windows users on the hotkey path should re-run cc-clip hotkey <host> --enable-autostart so the loop restarts on the new binary.

Not in This Release

  • The Windows paste fix is not verified on real hardware. There is no Windows machine behind this release. The new windows-latest job runs the Windows-only unit tests for the first time, but whether SendInput actually pastes into Wave is unconfirmed — please report on #140 either way. If it still does nothing for you, --no-restore is the fallback that works regardless.
  • Cursor notifications are not verified against a real cursor-agent. Cursor's CLI hook support has a history of firing unevenly, and cc-clip records this adapter as installed-but-unverified for that reason. Reports welcome on #109.
  • Mouse selection in your local terminal still does not reverse-copy, and cannot — see docs/reverse-copy.md for why and for the two configurations that do work.
  • Reverse image copy is still unimplemented (#128); no motivating case yet.
  • Persistent per-host SSH tunnels (#108) and notification icon/sound settings (#92) remain open.

Verification

V=0.11.0
gh release download "v$V" --repo ShunmeiCho/cc-clip \
  --pattern "cc-clip_${V}_darwin_arm64.tar.gz" --pattern "checksums.txt"
shasum -a 256 -c checksums.txt --ignore-missing

Full Commit List

  • 98f2add feat(notify): Cursor CLI notifications via ~/.cursor/hooks.json (#109)
  • 41f6c5e docs: --no-restore does not stop the keystroke, it makes it optional
  • fa172c4 docs: reverse-copy guide, and stop labelling our own notification unverified (#128)
  • 9f083a6 fix(windows): deliver paste with SendInput, add hotkey --no-restore, stop losing the PID file (#140)
  • 906bba1 feat(shim): transparent reverse copy — clipboard writes land locally (#128 phase 2)
  • 6ed1699 docs(i18n): mirror v0.10.0 features to zh/ja READMEs
  • 7694090 docs: README tagline covers Cursor and reverse copy
  • 7b477fb feat(doctor): cover the notification bridge (#22 P1)
  • 041fbce refactor: split main.go into connect.go / notify.go / serve.go (#20 I1)

Full diff: v0.10.0...v0.11.0

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 17:06
a1e63f4

What's New in v0.10.0

Three features. Two of them close long-standing gaps in what the tunnel could carry; the third stops cc-clip from replacing binaries a package manager owns.

cc-clip copy — the clipboard now runs both ways

Copying text out of a remote CLI by mouse selection copies what the terminal rendered: a long command soft-wrapped at the terminal width comes out with hard newlines at every visual break. That path is unfixable — the mangling happens in your terminal emulator. So cc-clip now bypasses it entirely:

cat deploy.sh | cc-clip copy      # on the remote: bytes land on your LOCAL clipboard verbatim
fc -ln -1     | cc-clip copy      # copy the command you just ran, wrap-free

Piped text never touches terminal rendering, so embedded and trailing newlines survive exactly. Auth rides the existing Bearer token; the body is capped at CC_CLIP_MAX_TEXT_MB (default 1MB).

Every accepted write raises a calm local notification ("A remote session copied N bytes to this clipboard"). That is deliberate and not configurable off in this release: a remote that can write your clipboard is a paste-hijack primitive, and silent writes are the failure mode. The notification names the byte count, never the content.

Cursor CLI target (#109)

cc-clip setup myserver --cursor

Cursor's clipboard reader shells out to xclip/wl-paste in shapes the shim already intercepts, so image paste works with no new transport. One prerequisite the deploy cannot satisfy: Cursor only reads the clipboard when DISPLAY or WAYLAND_DISPLAY is set in its shell (echo $DISPLAY to check; ssh -X or export an existing display). cc-clip deliberately does not invent one — a DISPLAY with no X server behind it would break clipboard fallback for every other tool in that shell. The setup output explains this, plus a timeout tweak for large images. Cursor notifications are not wired up yet.

Package-managed remote binaries — --use-remote-bin (#110)

Contributed by @Qu4tro. If nix, home-manager, pipx, or your distro's package manager owns cc-clip on the remote, cc-clip setup myserver --use-remote-bin keeps it that way: the executable is resolved under your remote login shell's PATH (so user-profile package managers are actually found), fingerprinted, and used as-is — nothing is uploaded. The mode is remembered in the host's deploy state, so later connect runs (including the connect <host> --force line cc-clip update suggests) keep it without the flag; deploy with --local-bin to switch back.

cc-clip status now catches a stale daemon

Replacing the binary in place never restarted the launchd service, so the running daemon could silently lag your binary — the reason past release notes had to insist on cc-clip update over a manual copy. /health now reports the daemon's version and cc-clip status warns when they provably differ, with the restart command. No warning is printed when honesty is impossible (pre-v0.10.0 daemon, dev build) — a false "stale daemon" warning would teach you to ignore the real one.

Behavior notes

  • New notification after remote copies. "Clipboard set by remote" appearing after you run cc-clip copy is the feature working, not noise — see above.
  • cc-clip copy against an old local daemon fails with instructions. If the local machine still runs a pre-v0.10.0 daemon, the remote command reports the daemon does not support clipboard write; upgrade cc-clip on the local machine and restart it (cc-clip update). Upgrade order below.
  • Remote deploy state moves to schema v2 (it now records the package-managed mode). A machine still running v0.9.x cc-clip that connects to a host deployed by v0.10.0 will refuse to overwrite that state without --force — intentional, so an older binary cannot silently strip the new marker.

Upgrade

Order matters this time: local first, then each remote host.

# 1. Local machine — also restarts the daemon (required for cc-clip copy and the version field)
cc-clip update

# 2. Each remote host — the binary hash changed, so connect re-uploads automatically
cc-clip connect myserver

cc-clip copy needs both ends on v0.10.0: the remote binary provides the command, the local daemon provides the endpoint. Fresh installs: install.sh (macOS/Linux) / install.ps1 (Windows) as usual.

Not in This Release

  • Shim interception of clipboard writes (xclip without -o, wl-copy), which would land remote TUIs' own copy actions on your local clipboard — #128 phase 2.
  • Cursor notifications — tracked on #109, awaiting real-host confirmation of the --cursor target.
  • doctor coverage of the notification bridge#22's last open item.
  • Managed persistent per-host SSH tunnels#108, design agreed, implementation in progress by @paigeman.
  • Per-tool notification sounds/icons#92, pending a config-format decision.

Verification

V=0.10.0
PLATFORM=darwin_arm64   # or darwin_amd64, linux_amd64, linux_arm64
curl -fsSLO https://github.com/ShunmeiCho/cc-clip/releases/download/v${V}/cc-clip_${V}_${PLATFORM}.tar.gz
curl -fsSLO https://github.com/ShunmeiCho/cc-clip/releases/download/v${V}/checksums.txt
shasum -a 256 --ignore-missing -c checksums.txt

Full Commit List

  • a1e63f4 docs: the /health version field ships in v0.10.0, not v0.9.3 (#134)
  • d379ecf test: lift cmd/cc-clip coverage past the 30% target (#20 I4) (#133)
  • 69c79d5 feat: daemon version consistency check and LocalCommand docs (#22 P2+P3) (#131)
  • 95839e2 feat: cc-clip copy — reverse clipboard, remote stdin to local clipboard (#128) (#129)
  • dc5d049 feat: add Cursor CLI deployment target (#109) (#126)
  • 982195c feat: support package-managed remote binaries (#111)
  • 1ec2b0b docs: record the remote PATH prelude pitfall (#125)
  • 543dc35 ci: gate the release on the same checks CI runs (#123)

Full diff: v0.9.2...v0.10.0

v0.9.2

Choose a tag to compare

@github-actions github-actions released this 15 Aug 15:20
1579564

What's New in v0.9.2

A correctness release. Two of the three fixes make cc-clip report problems it previously hid — if a new warning appears right after upgrading, please read "If you see a new message" below before assuming this release broke something.

Fixes

  • Windows paste no longer fires into the wrong window (#43, #115): cc-clip send --paste and the Alt+Shift+V hotkey put the remote path on the clipboard, wait, then synthesize Ctrl+Shift+V — which went to whatever window was focused at that moment. The gap was wider than --delay-ms, because a fresh PowerShell process has to start first. Switching windows in that gap delivered the remote path into whatever you switched to: a password manager, a chat input, a browser URL bar. cc-clip now records the focused window before touching the clipboard, re-checks it before the keystroke, and aborts without typing anything if it moved — or if Windows reports no foreground window at all, which happens briefly while a window is losing activation.

  • The tunnel check now proves the daemon is actually there (#22, #114): cc-clip connect and cc-clip doctor decided the tunnel was healthy from a bare TCP handshake. An sshd left over from a previous SSH session keeps the forwarded port open after its client is gone, so the handshake succeeded while nothing reached the daemon — and cc-clip printed tunnel verified for a tunnel that carried nothing. Both commands now ask the daemon to identify itself through the forward via GET /health, and distinguish five outcomes instead of two: healthy, nothing listening, port held but no daemon answering, reachable-but-unverifiable, and check-did-not-complete. Only a daemon that answers counts as healthy.

  • /notify says which authentication step failed (#20, #116): a missing Authorization header, a malformed one, and a genuinely invalid nonce all returned the same invalid notification nonce, so ~/.cache/cc-clip/notify-health.log could not tell them apart. Each now has its own message. This also closes a parsing gap: an Authorization header carrying a bare nonce without the Bearer prefix used to be accepted, and is now rejected. Every cc-clip component already sends the Bearer form, so only hand-rolled senders are affected.

If you see a new message

WARNING: port 18339 is held on the remote, but no cc-clip daemon answered.

Your tunnel was already not working; v0.9.1 called it tunnel verified anyway. The message names both causes: a stale sshd still owning the forward — lsof -ti tcp:18339 on the remote — or a live forward with no local daemon running (cc-clip serve).

One false alarm to know about: a local daemon still running a v0.7.7-or-older build is also reported as stale, even when the tunnel is fine. Those builds answer /health with {"status":"ok"} and no service field, which is what the new check matches on (the field was added in v0.8.0). Restarting the daemon on the new binary clears it — cc-clip update does this for you.

focus changed during paste; paste aborted, nothing was typed

The paste was withheld on purpose and nothing reached the other window. Re-focus the target window and press the hotkey again.

port 18339 reachable but daemon liveness unverified (no curl on remote)

The remote has no curl, so the daemon could not be asked to identify itself. This is not a clipboard failure — install curl on the remote for a real verification.

Behavior changes worth checking if you script around cc-clip

  • cc-clip send --paste now exits 1 on a focus abort, after already printing the remote path to stdout. The upload succeeded and the remote file exists; only the paste was withheld.
  • The connect success line changed from tunnel verified (via existing SSH session) to tunnel verified (cc-clip daemon answered through the existing SSH session).
  • cc-clip doctor now skips the end-to-end image probe unless the tunnel check is fully OK, so on a broken tunnel the failing row moves from image-probe to tunnel and the image-probe row disappears.

Other Improvements

  • The vulnerability scan in CI now runs against the current Go release instead of the pinned go.mod floor. Previously every new Go standard-library advisory turned CI red with no source change — that happened twice in three days (#113, #119).
  • CI now enforces the existing .gitignore rule keeping per-machine agent tool configuration (.claude/, .codex/, .agents/, AGENTS.md) out of the repository (#120).
  • docs/windows-quickstart.md and docs/troubleshooting.md no longer teach the bare TCP tunnel check that #114 removed for being wrong (#122).
  • CLAUDE.md corrected to describe the settings-first Claude hook path accurately (#84, #117).
  • READMEs redesigned and shortened in all three languages. Documentation only.
  • Go floor moved to 1.25.13. This affects source builds only (make build, go install, and connect's cross-compile fallback), and only with GOTOOLCHAIN=local on an older Go. Release binaries and cc-clip update are unaffected.

Upgrade

macOS / Linux, existing install:

cc-clip update

Prefer this over replacing the binary by hand. The /notify fix lives in the daemon and only takes effect once the daemon restarts; cc-clip update reinstalls the service (with rollback if the new binary fails to come up), while an in-place copy leaves the old daemon running.

macOS / Linux, fresh install:

curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | sh

Windows:

irm https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.ps1 | iex

Remote hosts: no redeploy required. Nothing installed on the remote changed in this release — not the shim, the hook script, the settings hooks, nor the X11 bridge. Re-running cc-clip connect <host> --force is optional and will simply re-upload the binary.

Not in This Release

  • Package-managed remote binaries (--use-remote-bin) — #110, implementation under review in #111.
  • Managed persistent per-host SSH tunnels#108, design agreed, phased implementation pending.
  • Cursor CLI support#109, blocked on a DISPLAY design decision.
  • Per-tool notification profiles (sound and icon per CLI) — #92, follow-up to the global settings shipped in #95.
  • Automatic cleanup of a stale remote sshd#22 deliberately stops at precise diagnosis. Killing a remote sshd that cc-clip cannot positively identify as its own is a worse failure mode than telling you exactly what to end.
  • cc-clip doctor coverage of the notification bridge#22, still open; doctor currently checks the clipboard path only.

Verification

V=0.9.2
PLATFORM=darwin_arm64   # or darwin_amd64, linux_amd64, linux_arm64
curl -fsSLO https://github.com/ShunmeiCho/cc-clip/releases/download/v${V}/cc-clip_${V}_${PLATFORM}.tar.gz
curl -fsSLO https://github.com/ShunmeiCho/cc-clip/releases/download/v${V}/checksums.txt
shasum -a 256 --ignore-missing -c checksums.txt

Full Commit List

  • 1579564 docs: align tunnel troubleshooting with the health probe (#22 P0 follow-up) (#122)
  • b8a8b90 docs: correct CLAUDE.md notification-path and hook-injection pointers (#84) (#117)
  • b6d466c fix(daemon): distinguish /notify auth failure classes (#20 I3) (#116)
  • 0184d8d fix(windows): abort paste when focus moves between copy and keystroke (#43) (#115)
  • 942b584 fix(tunnel): verify daemon liveness instead of TCP reachability (#22 P0) (#114)
  • deb5e95 ci: scan with current Go, and enforce the agent-config gitignore policy (#120)
  • fe13d28 fix(ci): bump Go floor to 1.25.13 to clear GO-2026-6089/6090/6218 (#119)
  • 5958436 fix(ci): bump Go floor to 1.25.12 to clear GO-2026-5856 (#113)
  • becdae8 docs(i18n): sync redesigned README translations
  • e0d18e6 docs: redesign and streamline README
  • 80cbb6e chore(release): group changelog into Features/Fixes (#107)

Full diff: v0.9.1...v0.9.2

v0.9.1

Choose a tag to compare

@github-actions github-actions released this 28 Jun 11:50
757e2a3

What's New in v0.9.1

Fixes

  • N0 v0.7.0 detection is now robust on minimal SSH environments (#101, #106): cc-clip connect no longer aborts with exit 127 when coreutils (readlink/head/grep/wc/tr) aren't on the non-interactive SSH PATH (e.g. Coder workspaces, slim containers). PATH hardening now applies to every remote command via WrapRemoteShell, and detection fails closed only when it cannot verify a remote is uncorrupted.
  • Image-transfer notifications are deduplicated (#100): rapid re-fetches of the same clipboard image (clipboard managers, agent retries) no longer spam notifications — duplicates within a short window are suppressed by (session, fingerprint).
  • cc-clip update authenticates with GITHUB_TOKEN/GH_TOKEN (#104): avoids GitHub API 403 rate-limit failures on cc-clip update --check.
  • Clearer Codex notify errors (#104): the notify-config refusal reason is surfaced instead of a bare exit status 7.
  • Post-update redeploy reminder defaults to --all --force (#104): preserves the Claude shim on Codex hosts instead of suggesting --codex (which is Codex-only since v0.9.0). Codex-only users are pointed at --codex --force.

Experimental

  • Windows direct clipboard transport.

The auto-generated ECC bundle briefly merged in #99 was reverted in #102 — no user-facing change in this release.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 16 Jun 06:48

What's New in v0.9.0

cc-clip now adds per-target setup, expands clipboard support across remote CLI workflows, and wires notifications for Claude Code, Codex CLI, opencode, and Antigravity.

Highlights

  • Per-target setup. Pick what each host gets: --claude / --codex / --opencode / --agy, or --all for everything.
  • ⚠️ Breaking change — --codex is now Codex-only. In v0.8.x, --codex added Codex on top of the Claude shim. In v0.9.0 it installs Codex only — use --all to get both Claude and Codex on one host.
  • Notifications for more CLIs. Notification wiring now covers Codex CLI, opencode, and Antigravity, alongside Claude Code. (opencode/Antigravity integrations are installed during connect; end-to-end delivery is not yet host-smoke-verified. Antigravity is notify-only — no clipboard transport.)
  • Configurable notification sound tiers and a terminal-notifier app icon (#92, #95).
  • Safer cross-version deploys. A schema_version forward-downgrade guard stops an older cc-clip from silently clobbering a newer remote's deploy state.
  • Remote commands run under POSIX /bin/sh regardless of the login shell (#98).

Upgrading from v0.8.x

--codex changed meaning (see above) — use --all for Claude + Codex. Full migration notes: Upgrading from v0.8.x to v0.9.0.

curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | sh

On a v0.9.0 beta? Same feature set as stable — run cc-clip update to move to v0.9.0. If you pinned CC_CLIP_VERSION=v0.9.0-beta.x, drop the pin.


Changelog

  • eaea0a5 docs(i18n): mirror v0.9.0 stable docs to zh/ja READMEs

v0.9.0-beta.2

v0.9.0-beta.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 15 Jun 05:40

cc-clip v0.9.0-beta.2 (prerelease — opt-in)

⚠️ Beta / opt-in prerelease. GitHub's latest-release API only returns non-prerelease releases, so neither the default install.sh nor cc-clip update will hand you this build — v0.8.1 stays the stable default. You only get beta.2 by explicitly pinning the version below.

Incremental prerelease on the v0.9.0 line. It carries everything from v0.9.0-beta.1 (the large connect/setup deployment refactor, per-target setup, opencode & Antigravity notifications) — see those notes for the full v0.9.0 picture and rollback guidance — plus the changes below.

What's new since v0.9.0-beta.1

  • fix(connect): remote commands now run under POSIX /bin/sh regardless of login shell (#98). On hosts whose login shell is fish (or any non-POSIX shell), connect / send / doctor previously died with exit 127 because fish mis-parses the sh scripts cc-clip sends over SSH. Every remote command is now wrapped in /bin/sh -c '…', so it runs correctly no matter which shell sshd invokes. bash/zsh logins are unchanged.
  • feat(notify): configurable notification sound tiers + terminal-notifier app icon (#95). Notification urgency now maps to distinct sound tiers, and macOS notifications carry a proper app icon.
  • docs: beta references aligned to v0.9.0-beta.2 across README (en/zh/ja) and the command / notification reference docs.

Install (opt-in prerelease)

curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | CC_CLIP_VERSION=v0.9.0-beta.2 sh

cc-clip --version should then report v0.9.0-beta.2. Stable users are unaffected.


Changelog

  • 94d6626 docs(readme): add v0.9.0-beta.1 prerelease banner (en/zh/ja) (#91)
  • e7d8d74 feat: configurable notification sound tiers and terminal-notifier app icon (#92) (#95)
  • 5427d6d fix: run remote commands under POSIX /bin/sh regardless of login shell (#98)

v0.9.0-beta.1

v0.9.0-beta.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Jun 15:10
291b88c

cc-clip v0.9.0-beta.1 (prerelease — opt-in)

⚠️ Beta / opt-in prerelease. This release must be published as
v0.9.0-beta.1 so GoReleaser marks it as a GitHub prerelease. GitHub's
latest-release API returns only non-prerelease, non-draft releases, so neither
install.sh (default) nor cc-clip update (default) will hand you this build.
You only get it by explicitly pinning the version below. Please read
Rollback first.

Why a beta

v0.9.0 is a large connect/setup deployment refactor. Instead of one person
exhaustively probing every remote environment, this prerelease invites testing
across diverse real setups. Bug reports (template at the bottom) are the whole
point of this build.

Install (opt-in)

curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh \
  | CC_CLIP_VERSION=v0.9.0-beta.1 sh

Quick start (after install)

  1. Make sure cc-clip is on your PATH — the installer prints the line to add to your
    shell profile (e.g. export PATH="$HOME/.local/bin:$PATH"), then reload your shell.
  2. Set up a remote host (pick the target for your CLI):
    • Claude Code only: cc-clip setup <host>
    • Claude Code + Codex CLI: cc-clip setup <host> --all (Codex needs Xvfb + sudo on the remote)
    • Codex CLI only: cc-clip setup <host> --codex (needs Xvfb + sudo)
    • opencode only: cc-clip setup <host> --opencode
    • Antigravity (agy) only: cc-clip setup <host> --agy
  3. Open a NEW SSH session (the tunnel activates on connect): ssh <host>
  4. Copy an image to your local clipboard, then press Ctrl+V (or your agent's paste key)
    in the remote CLI.
  5. Verify end-to-end any time: cc-clip doctor --host <host>

Full walkthrough (prerequisites, Codex specifics, Windows) — see the README Beta Quick Start:
https://github.com/ShunmeiCho/cc-clip#beta-quick-start-opt-in-v090-beta1

Rollback (if anything breaks)

cc-clip update --to v0.8.1
# or
curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh \
  | CC_CLIP_VERSION=v0.8.1 sh

As a beta user, prefer --to <tag> for any version change. A bare cc-clip update
follows /releases/latest (stable) and will move you OFF beta.

What's New

⚠️ BREAKING: --codex now installs Codex support ONLY

Previously --codex layered Codex on top of the Claude shim. It now installs
only Xvfb + x11-bridge (no Claude shim). For Claude Code and Codex on the
same host, use --all. Default (no flag) and --claude install the Claude shim.
An existing shim is never removed. A one-time deprecation notice prints on legacy
--codex; silence it with CC_CLIP_NO_DEPRECATION_NOTICE=1.

Multi-target connect / setup

Explicit deployment targets: --claude, --codex, --opencode, --agy, and
--all. One target per run, or --all for everything. (Free combinations like
--claude --codex together are NOT in this beta — see Known limitations.)

Notify bridge: opencode + Antigravity (agy)

  • opencode: clipboard paste already worked via the xclip/wl-paste shim;
    --opencode now also forwards opencode session.idle events as native
    notifications.
  • Antigravity (agy): --agy installs the agy-notify plugin (notify-only).

Deployment-resilience safety net (new in this build)

  • deploy-state SchemaVersion + connect forward-downgrade guard (an older
    cc-clip refuses to clobber a newer-schema remote).
  • uninstall --codex aborts against a newer-schema remote (no silent clobber).
  • CC_CLIP_VERSION install pinning = the rollback channel above.
  • sha256 checksum verified before cross-arch binary extraction.

Known limitations in this beta

  • Multi-target free combinations (e.g. --claude --codex) are not released
    yet — single target or --all only.
  • Antigravity (agy): notify-only; clipboard paste not yet implemented.
  • connect --force full-deploy path is not yet covered by a live-remote smoke.
    (The uninstall --codex newer-schema guard IS live-verified on a real host;
    connect --force is covered transitively + unit tests.)

Roadmap — where cc-clip is heading

Direction and priorities, not dated commitments. Order roughly reflects priority, not schedule.

  • Harden the v0.9.0 refactor (P1): live-remote coverage for connect --force,
    and an SSHSession test seam so deploy/uninstall orchestration is easier to test.
  • Multi-target free combinations (for example, --claude --codex together):
    under design; today target selection is one target or --all.
  • Antigravity (agy) clipboard paste: currently notify-only. Clipboard support
    needs real transport confirmation before implementation.
  • Easier distribution (P2): npm / npx entry + per-platform packages, so
    users have an alternative to the shell installer. This should be trialed in a
    separate beta first.
  • Docs: slim the README and move detailed workflows into focused docs.
  • Windows parity: reduce the gap between current Windows support and the
    native shim/update experience.

Principles we hold

  • Transparent & opt-in — intercept only the agent-specific calls cc-clip needs;
    prerelease builds are opt-in and are not returned by GitHub's latest-release API.
  • Security-first — loopback-only daemon, token + per-session nonce auth, and
    careful handling of secrets.
  • Reversible release installs — use CC_CLIP_VERSION or cc-clip update --to
    to move back to a known good version; schema guards avoid silently clobbering a
    newer remote state.
  • Fresh, not cached — clipboard transport fetches the current image on demand.

Help shape it — we want your input

This beta exists to learn from real environments. Tell us what to prioritize:

  • Which remote CLI should we support or harden next?
  • What is rough in setup / connect on your local OS + remote OS combination?
  • What would make daily use smoother?

Open or upvote a thread in
Discussions, or file an
Issue. A 👍 on an existing item
is a useful signal and helps us rank the backlog.

When reporting a beta issue, please include:

  • cc-clip --version
  • local OS and remote OS
  • the target flag used (--claude, --codex, --opencode, --agy, or --all)
  • relevant CLI versions (claude, codex, opencode, agy)
  • cc-clip doctor <host> output
  • remote ~/.cache/cc-clip/deploy.json if relevant, with host-specific details redacted

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 01 Jun 07:54
d3e4e44

Changelog

  • d3e4e44 fix(send): isolate ssh stderr and sentinel-parse remote home (#80) (#85)

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 31 May 15:59
dc6889e

cc-clip v0.8.0

A reliability round for the notification bridge and the send path, plus a new notification sound. Resolves #81 and #82; partially hardens #80 (see note).

Highlights

Notification sound (#81)

  • New cc-clip notify --sound <name> mapping to macOS system sounds (Glass, Ping, Basso, ...). Unknown names are ignored (never passed raw to the notifier).
  • --urgency 2 (critical) now plays a default Glass chime, including on the hook path (e.g. permission prompts).
  • First-use note: macOS may prompt to allow notifications for terminal-notifier; grant it, or the system suppresses the banner and sound.

Reboot-stable notifications (#82.2 / #82.3)

  • The daemon's notification-nonce registry is now persisted to disk (mode 0600, atomic write) and reloaded on startup, so a Mac reboot or daemon restart no longer breaks notifications with HTTP 401 — no manual reconnect required.
  • --token-only now also re-syncs the notification nonce.

More robust hook injection (#82.1 / #82.4)

  • The claude wrapper injects Stop/Notification hooks unconditionally (no more launch-time tunnel race); cc-clip-hook is fail-soft when the tunnel is down.
  • New persistent opt-out: cc-clip connect --no-hooks (and --hooks to re-enable). The marker survives wrapper reinstalls and --force, for users who manage hooks themselves.

Clean custom notifications (#82.5)

  • cc-clip notify --trusted suppresses the [unverified] prefix for nonce-authenticated local callers.
  • The Notification hook path now renders the message field as the body, so custom-text notifications are no longer empty.

Hardened upload verification (#80, partial)

  • cc-clip send now verifies the remote file size after upload and fails loudly (non-zero exit) on empty / missing / size-mismatch.
  • Note: this does NOT yet cover the wrong-path case reported in #80, where an SSH banner/warning pollutes the remote $HOME lookup so the file lands at a wrong path with the correct size. Root cause (stdout/stderr isolation in the remote-home lookup) is tracked for v0.8.1.

Project hardening

  • PR-level CI (build, vet, race tests, staticcheck, govulncheck) plus assorted correctness and atomicity fixes.

Known limitations

  • The wrapper-based hook injection can be wiped by Claude Code's own self-update (it rewrites the ~/.local/bin/claude symlink). Durable hook installation via a ~/.claude/settings.json merge or a plugin is tracked in #84. If you keep cc-clip-hook in your own ~/.claude/settings.json, that path is durable today.
  • send wrong-path under SSH banner pollution (#80) — fix tracked for v0.8.1; workaround: add LogLevel QUIET to ~/.ssh/config.

Upgrade

  1. cc-clip update
  2. Restart the daemon (macOS): cc-clip service uninstall && cc-clip service install
  3. Redeploy to remote hosts: cc-clip connect <host> --force

Full diff: v0.7.7...v0.8.0

v0.7.7

Choose a tag to compare

@github-actions github-actions released this 28 May 09:49
1cf1c4f

Patch release tightening the section-aware notify detector introduced in v0.7.6. Backward compatible. Recommended for users whose Codex config uses indented sub-tables.

Fix since v0.7.6

fix(shim): allow indented [section] headers in codex notify detector

v0.7.6's awk used /^\[/ to identify TOML section headers, matching only column-0 headers. But TOML 1.0.0 §Table treats leading whitespace on a section header line as whitespace and ignores it, so a perfectly legal [agents.X] was silently skipped — and any notify = beneath it was mis-classified as top-level, falsely tripping exit 7.

Fix: tighten the regex from /^\[/ to /^[[:space:]]*\[/, matching the symmetric [[:space:]]* tolerance already in place for the notify line itself.

-  /^\[/ { in_section = 1; next }
+  /^[[:space:]]*\[/ { in_section = 1; next }

Regression coverage

TestEnsureRemoteCodexNotifyConfigAllowsIndentedAgentSectionNotify — fixture contains a TOML body whose [agents.docs_researcher] block is indented; asserts the top-level injection succeeds and the agent-level notify is preserved verbatim. Without the fix this test fails with exit status 7.

Upgrade

curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | bash

Or, if you already have cc-clip installed:

cc-clip update

Verification

sha256sum -c checksums.txt --ignore-missing