Claude Code plugin
Know what the directory scan will hold, before you upload.
A skill and four small scripts. They run the upload checks on your machine, read the scan report in a screenful, and find a stubborn hold in about three uploads instead of guessing.
/plugin marketplace add gagoar/plugin-directory-preflight /plugin install plugin-directory-preflight@plugin-directory-preflight /reload-plugins
See it work
Run the gate. Fix everything it names. Upload once.
The scan names one match per upload. The gate names every match in the repository at once.
Before the fix
After the fix
FAIL scripts/status.mjs: line 55 has a template placeholder that names a credential, which the scanner reads as a credential lookup
FAIL README.md: line 152 has the glob ./docs/**, which covers 32 image or font file(s)
FAIL notes.js: line 3 has a command word on its own, which the scanner reads as a command that prints the environment
3 problem(s) in 41 files
checked 41 files, 0 problem(s)
Renamed the placeholder, narrowed the glob, reworded the call. One upload instead of three. Each of these is something the scan held a real plugin for. Without the gate it names one per upload.
Why this exists
One plugin took seventeen releases to clear.
The directory's upload scan cannot be run locally, and it reports only the first match in path order. Every fix revealed the next hold, and a fix in an earlier-sorting file could hide a later one.
Releases, one upload and one long report each, to clear a single plugin.
Match named per upload. Anything after it in path order stays hidden.
Uploads for the probe to pin a trigger to one line of a large file.
What you get
Four scripts and one skill.
The gate
Ten checks for what the scan held a plugin for: unscoped grants, big files, committed binaries, command words, credential-named placeholders, image names and globs and more. Runs in CI.
The installer
Copies the gate and a CI workflow into any plugin repo, including a
plugin/subdirectory.--checkreports drift.The report reader
Turns a 40k-token scan report into a screenful: the findings, the file named, and the files that sort before it and could be masking the next match.
The probe
Cuts a file into slices that sort in line order, so each upload halves the search. About three uploads reach a single line.
When the gate cannot explain a hold
Bisect it, don't guess.
The scan names the first matching file. Cut the suspect file into small files named in line order and upload that. The file it names is the slice; cut that slice again.
# round 1: 16 slices of the file credential_at probe/s1-11.js # round 2: cut that slice (75 lines) credential_at probe/s2-06.js # round 3: windows of 1..N lines credential_at probe/w01-02.js explain line 777 of the original file
The gate
Ten checks, each from a real hold.
What the scan holds a plugin forWhat a clean gate run clears
- CheckUnscoped grantsA skill, agent or command that pre-approves writing, editing or running commands with no path scope.
- CheckWhole-environment copiesCode, test files and comments that copy every variable instead of naming the ones they need.
- CheckCommitted binariesA native executable the scan cannot read.
- CheckFiles over 5 MiBThe plugin directory rejects any file over 5 MiB.
- CheckScripts and documents of 256 KiBThe scan reads a script or document only up to 256 KiB, then holds the plugin.
- CheckCommand words aloneA shell command that prints the environment, alone in a call, a condition or a pipe-joined word list.
- CheckCredential-named placeholdersA template placeholder whose expression names a key, token or secret.
- CheckImage globsA glob in a document that covers images or fonts the scan cannot read.
- CheckImage names in scriptsA script that names an image or a font that exists in the repository.
- CheckHost beside environmentA remote host and an environment reference in one script. Links can live in a Markdown file.
The gate is held to its own rules, comments and documents included, and a test runs it on this repository.
Install it in 10 seconds.
/plugin marketplace add gagoar/plugin-directory-preflight /plugin install plugin-directory-preflight@plugin-directory-preflight /reload-plugins