Windows Native Support: Instant Clipboard + Sandbox TCP Fallback#2917
Windows Native Support: Instant Clipboard + Sandbox TCP Fallback#2917claudlos wants to merge 8 commits into
Conversation
Applied Windows-specific changes from PR #2551 onto current main: Crash fixes: - memory_tool.py: fcntl import guard + msvcrt fallback - display.py: /dev/tty -> CON on Windows - persistent_shell.py + local.py: /tmp -> tempfile.gettempdir() - gateway.py: signal.SIGKILL -> SIGTERM on win32 New Windows features: - Native clipboard (image + text) via PowerShell - Windows Credential Manager for API keys (keyring) - Gateway service via Windows Task Scheduler - icacls file permissions, taskkill, wmic - Shift+Insert paste, improved Ctrl+V with text fallback - cmd.exe-safe shell quoting (shell_quote.py) - AF_UNIX sandbox detection for Windows 10+ Security: - Credential Manager instead of plaintext .env - icacls owner-only ACLs - SMS webhook binds localhost by default - shlex.split for quick commands on Unix Docs & tests: - WINDOWS.md documentation - windows-tests.yml CI workflow - Expanded test_windows_compat.py
The sandbox RPC previously required AF_UNIX sockets, which aren't available in stock CPython on Windows (the PR to add it, python/cpython#137420, is still unmerged). This made execute_code show red/disabled in the banner on native Windows. Changes: - _detect_transport() picks UDS or TCP at import time based on socket.AF_UNIX availability - Server side: binds AF_UNIX socket (Linux/macOS) or 127.0.0.1:0 random port (Windows) depending on transport - Generated hermes_tools.py: _connect() parses HERMES_RPC_SOCKET env var -- 'tcp:host:port' for TCP, file path for UDS - SANDBOX_AVAILABLE = True always, check_sandbox_requirements() always returns True - Removed dead 'not available on Windows' error gate - Updated tests: replaced windows_returns_error with sandbox_always_available, fixed class name corruption, updated skip messages execute_code now works on all platforms.
Replace PowerShell subprocess calls with ctypes win32 API for all clipboard check operations on native Windows: - _windows_has_image(): IsClipboardFormatAvailable (0.03ms vs 2-15s) - _windows_has_text(): IsClipboardFormatAvailable (instant) - _windows_get_text(): OpenClipboard/GetClipboardData/GlobalLock (instant) Image extraction (_windows_save) still uses PowerShell for DIB->PNG conversion via .NET System.Drawing, but now gates on the instant ctypes check first so PowerShell is only invoked when there's actually an image to extract. This fixes Ctrl+V feeling broken on Windows — the has_image check that fires on every keystroke was taking 2-15 seconds due to PowerShell cold-start overhead. Now it's sub-millisecond. Also fixed trailing logout corruption at EOF.
Adds docs/windows/ with: - index.html: Full writeup of Windows fixes (GitHub Pages ready) Covers clipboard ctypes upgrade, sandbox TCP fallback, CPython AF_UNIX build, and all four phases of Windows work - PR_DESCRIPTION.md: PR template with benchmarks and test results
Two layers of caching for the search_files tool: 1. Result Cache: caches ripgrep output keyed by search parameters. Invalidated when any file is written or patched via Hermes tools. 120s TTL, 64-entry LRU. Delivers ~5,000-30,000x speedup on repeated identical searches (1-2µs vs 10-30ms). 2. Trigram Index: in-memory inverted index built lazily in a background thread on first content search (500+ file threshold). Decomposes regex patterns into trigrams, intersects posting lists, passes only candidate files to rg via --files-from. Delivers 3-15x speedup on warm searches, with instant rejection (µs) for non-existent patterns. Write invalidation hooks in write_file_tool and patch_tool (both replace and v4a modes). Cleanup hooks in terminal_tool.py alongside existing clear_file_ops_cache calls. Includes design document for future persistent disk-backed index with git-anchored lifecycle (docs/instant-grep-plan.md). Inspired by: https://cursor.com/blog/fast-regex-search
install-windows.ps1 — two modes: 1. Run from inside a repo checkout: detects current branch, syncs source to %LOCALAPPDATA%\hermes-agent, builds from it. Useful for testing branches with Windows fixes. 2. Downloaded standalone (irm | iex): clones from GitHub, installs main branch. Both modes: checks Python 3.10+, creates venv, pip installs editable, creates hermes.bat launcher, adds to user PATH. One-liner install: irm https://raw.githubusercontent.com/claudlos/hermes-agent/windows-qol-local/scripts/install-windows.ps1 | iex Or from a local checkout: .\scripts\install-windows.ps1
On Windows machines with WSL2 installed, shutil.which("bash") can find
C:\Windows\System32\bash.exe (the WSL launcher) before Git Bash,
causing all terminal commands to silently execute inside WSL2 instead
of native Windows. Fix by checking known Git for Windows install paths
first, and filtering out System32/WindowsApps bash from PATH fallback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Hey @claudlos, I'd be very interested in this windows version of hermes agent... as a noob how do I go about implementing / installing your modified version? |
@wingraver |
Hey @claudlos, thanks for the response... I'm really interested in running with Hermes agent but would rather wait on a truly Windows based implementation... have had too many gotcha moments working with WSL2 from WindowsOS in the past. Either way, if you fork or can share some kind of guide on how-to... I'm sure a lot of folks would really appreciate it (myself included). |
|
Hey @claudlos, thanks for the follow-up... I checked it out and tried the install script on my Windows 10 machine... got this error at execution: |
@wingraver I patched it. Try again and let me know. |
Boom! It's successfully installed and a new Hermes agent user has been added to the World! ;0) Thanks a whole lot @claudlos, it is truly appreciated. Hopefully they see it fit to make this merge happen. Bless. |
Summary
Two fixes that make Hermes work properly on native Windows (no WSL required):
Also built CPython 3.13.12 from source with the AF_UNIX Windows patch — repo at claudlos/cpython-windows-afunix.
Clipboard: ctypes instead of PowerShell
Problem: Every Ctrl+V on Windows spawned a
powershell.exeprocess to check the clipboard. First call took 2-15 seconds (.NET cold start). Image paste felt completely broken.Fix: Native win32 API via
ctypes.windll.user32:has_clipboard_image()has_clipboard_text()get_clipboard_text()save_clipboard_image()Uses
IsClipboardFormatAvailable(no clipboard open needed),OpenClipboard/GetClipboardData/GlobalLock/wstring_atfor text. PowerShell only invoked when there's actually an image to extract (DIB to PNG needs .NET).82/82 clipboard tests pass.
Sandbox: Dual-Transport RPC
Problem:
execute_codeuses Unix domain sockets for parent-child RPC. Stock CPython on Windows doesn't havesocket.AF_UNIX(upstream PR python/cpython#137420 open since Aug 2025). Tool showed red/disabled in banner.Fix:
_detect_transport()picks socket type at import time:/tmp/hermes_rpc_xxx.sock(unchanged)127.0.0.1:0(OS picks random port)Env var
HERMES_RPC_SOCKETcarries either a file path ortcp:host:port. Generated child stub parses the prefix.SANDBOX_AVAILABLE = Truealways. No more red in the banner.28/28 tests pass (20 unit + 8 end-to-end with actual subprocess sandbox execution).
Bonus: CPython AF_UNIX Build
Built CPython 3.13.12 with AF_UNIX patch — 10 lines, 3 C files. Repo: claudlos/cpython-windows-afunix
When Hermes detects this build, it automatically uses UDS instead of TCP via
_detect_transport().Files Changed
tools/code_execution_tool.py— Dual-transport sandbox RPCtests/tools/test_code_execution.py— Updated + new transport testshermes_cli/clipboard.py— Native win32 ctypes clipboarddocs/windows/index.html— GitHub Pages writeupTesting