This release fixes issues for SREs watching stability and regressions.
✓ No known CVEs patched in this version
Topics
+13 more
Summary
AI summaryClipboard read operation no longer leaves the system clipboard locked due to goroutine thread migration.
Full changelog
Quick Start
- Download the binary for your OS below
- Run
agent-tool install(oragent-tool install claude) - Restart your IDE
- Done -- all tools work immediately, no permission popups
Or just ask your AI agent:
"Download agent-tool from https://github.com/knewstimek/agent-tool/releases/latest and run
agent-tool install"
Any capable AI coding agent (Claude Code, Codex, etc.) can handle the full download -> install -> restart flow automatically.
Tip: Add this to your CLAUDE.md or AGENTS.md so your agent prefers agent-tool over built-in tools:
Strict mode:
ALWAYS use agent-tool MCP tools (mcp__agent-tool__*) instead of built-in file tools. agent-tool preserves file encoding and respects .editorconfig indentation settings.
Soft mode:
Prefer agent-tool MCP tools (mcp__agent-tool__*) over built-in file tools when available.
What's New
Fix: wintool clipboard read no longer leaves the system clipboard locked (round 2)
v0.8.6 closed the lock-count and owner-hwnd paths that could leave the clipboard stuck after a wintool operation=clipboard call, but the same symptom kept resurfacing intermittently. After the call -- sometimes -- no application could read or write the clipboard, and even cmd /c "echo off | clip" failed. The only recovery was killing the agent-tool process (typically by restarting the IDE).
Direct diagnosis on a stuck instance: GetOpenClipboardWindow() reported the agent-tool process itself as the holder. So this was not an external app fighting over the clipboard -- agent-tool had opened the clipboard and never released it from the system's point of view, even though every OpenClipboard in the code had a matching CloseClipboard call (verified by inspection and by the lock count drain added in v0.8.6).
Root cause. The Win32 clipboard APIs (OpenClipboard, CloseClipboard, GetClipboardData, GlobalLock, GlobalUnlock) are bound to the calling OS thread. Go goroutines, however, can migrate between OS threads at any syscall boundary -- and the clipboard read path makes many syscalls (IsClipboardFormatAvailable, OpenClipboard, GetClipboardData, GlobalLock, GlobalSize, GlobalUnlock, CloseClipboard, plus os.WriteFile for the save path). When the runtime moved the goroutine to a different OS thread between OpenClipboard and CloseClipboard, the second call ran on a thread that had not opened the clipboard, so it became a silent no-op. The original thread remained the legitimate owner from the kernel's point of view and held the clipboard for the rest of the agent-tool process lifetime. This was probabilistic, which is exactly the "sometimes works, sometimes breaks the whole system" pattern users were hitting.
The previous round of fixes (GlobalUnlock drain, retry-on-contention, real owner hwnd, short hold time) all reduced the surface area but none of them prevented the goroutine from migrating between paired calls -- so the failure could still occur, just less often.
Fix. All clipboard work now runs on a single dedicated goroutine that is permanently pinned to one OS thread via runtime.LockOSThread:
- A worker goroutine is spawned on first clipboard use (lazy
sync.Once) and never returns. It callsruntime.LockOSThreadimmediately and neverUnlockOSThread, so its OS thread is fixed for the lifetime of the process. CreateWindowExWfor the message-only owner hwnd runs on this same worker thread, so the window's owning thread and the clipboard-lock thread are guaranteed to coincide.- The public
opClipboardentry point becomes a thin dispatcher: it sends the actual work to the worker via a channel and waits for the reply. - Worker-side
recover()ensures a panic in the clipboard path still returns a reply, so callers cannot block forever.
Goroutine migration between paired Win32 clipboard calls is now structurally impossible: there is exactly one OS thread that ever opens, reads, and closes the clipboard, and that thread cannot move. Concurrent wintool clipboard calls from multiple goroutines are also serialized for free by the channel.
This is the same architecture used by golang.design/x/clipboard, atotto/clipboard, and other production Go clipboard libraries -- it is the standard answer to Win32's per-thread clipboard ownership model.
Full Changelog: https://github.com/knewstimek/agent-tool/compare/v0.8.6...v0.8.7
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About knewstimek/agent-tool
Encoding-aware, indentation-smart file tools for AI coding agents. 20+ tools including read/edit with automatic encoding detection, smart indentation conversion, SSH, SFTP, process management, and system utilities. Preserves file encoding (UTF-8, EUC-KR, Shift_JIS, etc.) and respects .editorconfig settings.
Related context
Beta — feedback welcome: [email protected]