Skip to content

fix(hooks): add Windows .cmd wrapper so extensionless hook resolves and allows shells#2

Open
JillRegan wants to merge 5 commits into
mainfrom
jill/bypass-check-for-windows
Open

fix(hooks): add Windows .cmd wrapper so extensionless hook resolves and allows shells#2
JillRegan wants to merge 5 commits into
mainfrom
jill/bypass-check-for-windows

Conversation

@JillRegan
Copy link
Copy Markdown

@JillRegan JillRegan commented May 13, 2026

Problem

When installed on Windows the hook pointed at the Bash file, Windows did not run it as a shell hook the way macOS/Linux do. The OS has no native 'run this shebanged Bash file” behaviour, so the command often failed to produce valid hook JSON on stdout (no output). It triggered file association so the scripts/validate-mounted-env-files.sh file opened in an editor on every command run instead of executing as a hook.

Fix

Update the hook command in hooks.json to ./scripts/validate-mounted-env-files with no file extension (so dropping the .sh). On macOS and Linux still run the Bash validator as before.

On Windows the shell resolves that name using PATHEXT and picks validate-mounted-env-files.cmd, a small cmd wrapper that calls PowerShell that reads the hook prints JSON with permission: allow and a short message that Environments validation was skipped.

  • Add scripts/validate-mounted-env-files.cmd: small cmd wrapper that invokes PowerShell and returns allow and a clear skip message.
  • hooks.json on ./scripts/validate-mounted-env-files (no extension) so one command works on Mac/Linux and windows

Regression Tested on macOS

I followed these steps from cursor on installing the plugin locally to ensure no regressions. Once installed tested with enviornments.toml, and mounted env. Confirmed both paths still produce expected allow / deny.

Windows Testing

I tested this on my personal Windows laptop. Like above I installed the plugin locally and then ran commands via the agent. Confirmed each time an allow was produce in the execution logs, and no file opened in the editor.

How to Test

Follow these steps to install the plugin locally and then test with mounted env files.

  • Create a folder for your plugin: ~/.cursor/plugins/local/my-plugin
  • Copy your plugin files into that folder. Make sure .cursor-plugin/plugin.json is at the plugin root.
  • Restart Cursor, or run Developer: Reload Window.
  • Use a 1Password environment and mount it to the project you are testing and run a command.
  • Test unmounting to confirm a deny

timestamp=$(date +"%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$(date +%s)")
local log_message="[${timestamp}] [validate-mounted-env-files] $*"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The below changes looks to just be formatting changes. No actual script changes were made besides the above fallback for skipping windows. The file was renamed though scripts/validate-mounted-env-files.sh -> scripts/validate-mounted-env-files

@JillRegan JillRegan marked this pull request as ready for review May 14, 2026 12:12
esac

unset -f _esc 2>/dev/null || true

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case where the shell used is Git Bash I have added this fallback. I read that Cursor's agent could use Git Bash but had trouble executing that on my Windows.

While I was able o set the default terminal to Git Bash, Cursor seemed to consistently use PowerShell. I tested this by running the following in a separate Git Bash terminal to confirm an allow was produced:

echo '{"command":"echo test","workspace_roots":["/c/path/to/some/project"]}' | ./scripts/validate-mounted-env-files

@JillRegan JillRegan requested a review from rishiy15 May 14, 2026 12:19
# On Windows, if Bash runs this file (Git Bash, MSYS, Cygwin, etc.), return allow and skip validation
# Cursor on Windows normally runs the .cmd file instead; this is for when Bash runs it.
WIN_SKIP_MSG='1Password Environments are not currently supported on Windows. Environment validation was skipped.'
_esc() { printf '%s' "$1" | sed 's/\\/\\\\/g;s/"/\\"/g'; }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we reuse the existing escape_json_string() function?

Comment on lines +11 to +17
case "$(uname -s 2>/dev/null)" in
MINGW* | MSYS* | CYGWIN*)
cat >/dev/null 2>&1 || true
printf '%s\n' "$WIN_SKIP_JSON"
exit 0
;;
esac
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could actually extend this early-exit logic to any unsupported OS (e.g. FreeBSD) by reusing detect_os() and having a more generic user-facing message. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants