Skip to content

fix(files): discover plugin executables by extension on Windows - #314

Merged
peteski22 merged 2 commits into
fix/windows-permissionsfrom
fix/windows-plugin-discovery
Sep 14, 2026
Merged

peteski22 merged 2 commits into
fix/windows-permissionsfrom
fix/windows-plugin-discovery

Conversation

@peteski22

Copy link
Copy Markdown
Contributor

Description

Stacked on #309. Base is fix/windows-permissions; retarget to main once #309 merges. Only the top two commits belong to this PR.

mcpd never discovered a plugin on Windows. DiscoverExecutablesWithPaths treated a file as executable only when an execute bit was set. Windows has no execute bit and Go reports every file as 0666, so the plugin directory always appeared empty and every configured plugin was reported as missing (#313).

Two commits:

  1. Discover plugin executables by extension on Windows. Executability is decided per platform behind build tags. Unix keeps the execute-bit check. Windows accepts a file whose extension is listed in PATHEXT (default .COM;.EXE;.BAT;.CMD), the same rule the shell and exec.LookPath apply, and registers it under its name with the extension removed so name = "my-plugin" matches my-plugin.exe. When several candidates share a name, PATHEXT order decides. A filestest helper names fixtures portably so the existing discovery tests run unchanged on every platform, plus Windows-only tests for the PATHEXT rules.
  2. Docs. The plugin directory section describes the executable rule per platform, and the troubleshooting tip no longer sends Windows users to ls -l.

PR Type

  • New Feature
  • Bug Fix
  • Refactor
  • Documentation
  • Infrastructure / CI

Relevant issues

Fixes #313
Refs #218

How to test

go test ./...
GOOS=linux go vet ./... && GOOS=darwin go vet ./... && GOOS=windows go vet ./...

On Windows this turns internal/files, internal/plugin, internal/config and cmd/config/plugins green; with #309 the whole suite passes on Windows. To see it in action, drop a foo.exe into a plugin directory and configure name = "foo".

Checklist

  • I understand the code I am submitting.
  • I have added or updated tests that cover my change.
  • I ran relevant checks locally (make lint, make test).
  • Documentation was updated where necessary.
  • I have read and followed the contribution guidelines.

AI Usage

  • No AI was used.
  • AI was used for drafting/refactoring.
  • This is fully AI-generated.

AI Model/Tool used: Claude Code (Claude Fable 5.1)

Any additional AI details you'd like to share: The change set was drafted with Claude Code and reviewed commit by commit by the author, with naming, structure and history revised during that review.

  • I am an AI Agent filling out this form (check box if true)

DiscoverExecutablesWithPaths treated a file as executable only when an
execute bit was set. Windows has no execute bit and Go reports every
file as 0666, so no plugin was ever discovered there and configured
plugins were reported as missing.

Decide executability per platform behind build tags. Unix keeps the
execute-bit check. Windows accepts a file whose extension is listed in
PATHEXT (default .COM;.EXE;.BAT;.CMD), the same rule the shell and
exec.LookPath apply, and registers it under its name without the
extension so a plugin configured as "my-plugin" matches my-plugin.exe on
disk. When several candidates share a name the PATHEXT order decides.

A filestest package names executable fixtures portably so the existing
discovery tests run unchanged on every platform.

Fixes #313
The plugin directory section stated the execute-bit rule as universal.
Document the Windows rule: extensions listed in PATHEXT are executable,
the extension is stripped when matching the configured name, and
PATHEXT order breaks ties.
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: bcbb5363-5f09-49e8-9a6f-d8863874e3e2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@peteski22
peteski22 force-pushed the fix/windows-permissions branch from 0f5f1fd to 457e693 Compare September 3, 2026 17:20
@peteski22
peteski22 merged commit 046d109 into fix/windows-permissions Sep 14, 2026
1 check passed
@peteski22
peteski22 deleted the fix/windows-plugin-discovery branch September 14, 2026 13:42
peteski22 added a commit that referenced this pull request Sep 16, 2026
* fix(files): discover plugin executables by extension on Windows

DiscoverExecutablesWithPaths treated a file as executable only when an
execute bit was set. Windows has no execute bit and Go reports every
file as 0666, so no plugin was ever discovered there and configured
plugins were reported as missing.

Decide executability per platform behind build tags. Unix keeps the
execute-bit check. Windows accepts a file whose extension is listed in
PATHEXT (default .COM;.EXE;.BAT;.CMD), the same rule the shell and
exec.LookPath apply, and registers it under its name without the
extension so a plugin configured as "my-plugin" matches my-plugin.exe on
disk. When several candidates share a name the PATHEXT order decides.

A filestest package names executable fixtures portably so the existing
discovery tests run unchanged on every platform.

Fixes #313

* docs(plugins): describe how plugin executables are discovered on Windows

The plugin directory section stated the execute-bit rule as universal.
Document the Windows rule: extensions listed in PATHEXT are executable,
the extension is stripped when matching the configured name, and
PATHEXT order breaks ties.
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.

1 participant