feat: Windows support#45
Open
shakedarazi wants to merge 6 commits into
Open
Conversation
herdr's IPC on Windows is a named pipe at \.\pipe\<socketPath>, not a unix socket. Add build-tagged dialHerdr: named pipe on Windows (retrying on ERROR_PIPE_BUSY), unix socket elsewhere. Stdlib only.
One platform descriptor selected once replaces scattered runtime.GOOS checks: PowerShell vs sh, powershellQuote vs posixQuote, pane -windows suffix, and the {{opener}} command (Start-Process/open/xdg-open). Quick-action examples use {{opener}} so they work cross-OS.
Windows can't spawn the extensionless PE, so each action/pane gets a -windows twin running herdr-plus.exe via a powershell wrapper (relative-path spawn needs a shell). Panes omit -NonInteractive (interactive TUIs); actions/events keep it. manifest_test scans command args for the .exe.
os.UserHomeDir error was silently discarded; on Windows a missing USERPROFILE would resolve ~ to a wrong path. Return the error when the path needs home; add displayWorkingDir for UI paths that can't surface one. Also routes pane opens through paneEntrypoint.
Add windows/amd64 to goreleaser (skip windows/arm64) and override the archive format to .zip for Windows.
There was a problem hiding this comment.
Pull request overview
This PR adds first-class Windows support to the herdr-plus plugin by introducing Windows-specific IPC dialing (named pipes), centralizing shell/quoting behavior behind a platform descriptor, and updating the plugin manifest and release packaging to include Windows binaries and entrypoints.
Changes:
- Add OS-specific abstractions for shell execution/quoting, pane entrypoint selection, and “open” command templating (
{{opener}}). - Add build-tagged IPC dialing to support Windows named pipes while preserving Unix domain socket behavior elsewhere.
- Update plugin manifest, examples, tests, and GoReleaser packaging to support Windows install/run flows.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| util.go | Removes POSIX-only shellQuote helper now centralized elsewhere. |
| shell.go | Introduces platform descriptor (shell, quoting, pane suffix, opener) and helpers. |
| shell_test.go | Adds cross-platform unit tests for quoting/shell dispatch/entrypoint/opener. |
| quickactions.go | Uses paneEntrypoint() so the correct pane id is opened per OS. |
| projectsmodel.go | Switches UI display to use displayWorkingDir() for non-error UI contexts. |
| projectsmodel_test.go | Adjusts assertions for platform-native path normalization. |
| projects.go | Uses paneEntrypoint() and propagates expandedWorkingDir() errors when opening projects. |
| project.go | Makes expandedWorkingDir() return (string, error), adds displayWorkingDir() helper. |
| project_test.go | Updates tests for expandedWorkingDir() error return and separator normalization. |
| manifest_test.go | Adds test ensuring manifest includes required Windows entries/commands. |
| herdrdial_windows.go | Adds Windows dialHerdr() using named pipes with retry on ERROR_PIPE_BUSY. |
| herdrdial_other.go | Adds non-Windows dialHerdr() using unix domain sockets. |
| herdr.go | Switches client transport to dialHerdr() to unify Windows/Unix IPC. |
| herdr-plugin.toml | Adds Windows platform + build step + windows-twin actions/panes/events. |
| examples/quick-actions/open-working-dir.toml | Uses {{opener}} and updates description to be cross-platform. |
| examples/quick-actions/open-repo.toml | Replaces hardcoded open with {{opener}}. |
| examples/quick-actions/google.toml | Replaces hardcoded open with {{opener}}. |
| examples/quick-actions/google-search.toml | Replaces hardcoded open with {{opener}}. |
| examples/quick-actions/github.toml | Replaces hardcoded open with {{opener}} and documents it. |
| action.go | Adds template funcs ({{opener}}) and routes execution via shellCommand(). |
| action_test.go | Updates expected quoting to be OS-specific; adds opener helper test. |
| action_run_integration_test.go | Adds integration test to validate quoting round-trip through real shells. |
| .goreleaser.yml | Adds Windows builds and ships Windows archives as .zip. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
216
to
219
| // expandedWorkingDir resolves the project's working directory to an absolute | ||
| // path, expanding a leading ~ to the home directory and any $VARS in the path. | ||
| // An empty working_dir defaults to the user's home directory, so a minimal | ||
| // project still opens somewhere sensible. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Windows support to the herdr-plus plugin. Verified end-to-end against a live herdr 0.7.4-preview on Windows 11 (Go 1.26.2); Linux/macOS behaviour unchanged.
What was needed on Windows
Three platform differences drove the change:
\\.\pipe\<socketPath>(the on-diskherdr.sockis just a liveness marker). Protocol is identical newline-delimited JSON, no token handshake. Added build-taggeddialHerdr: named pipe on Windows (retrying onERROR_PIPE_BUSY), unix socket elsewhere. Stdlib only, no new deps.CreateProcessWappends.exe, so the binary isherdr-plus.exeand each action/pane gets a-windowstwin (herdr requires unique action/pane ids; duplicate eventon=differentiated byplatformsis allowed). Relative-path spawn resolves against herdr's cwd, so Windows entries shell throughpowershell -Command "& .\bin\herdr-plus.exe <sub>". Panes omit-NonInteractive(interactive TUIs); actions/events keep it.platformdescriptor inshell.go(PowerShell vssh, PowerShell vs POSIX quoting, pane suffix,{{opener}}=Start-Process/open/xdg-open) — no scatteredruntime.GOOS.Verified
go build(windows/linux/darwin),go vet ./...,go test ./...all green.platforms = [linux, macos, windows].worktree.created→ auto-layout all exercised on the live host.~/$VARSexpansion unit-tested on Windows.Also
expandedWorkingDirnow surfaces a home-dir resolution error instead of silently discarding it (a missingUSERPROFILEwould have resolved~to a wrong path).amd64binaries as.zip.🤖 Generated with Claude Code