Skip to content

Guide

Getting a plugin through the directory scan

The scan cannot be run locally, so this plugin runs an approximation of it, reads the report compactly, and bisects what the approximation cannot explain.

Install

Install
/plugin marketplace add gagoar/plugin-directory-preflight
/plugin install plugin-directory-preflight@plugin-directory-preflight
/reload-plugins

Then ask Claude to run the plugin directory preflight on the repository you are about to upload.

The workflow

  1. Find the plugin root: the directory with .claude-plugin/plugin.json, at the repo root or in plugin/.
  2. Check the gate is current: node scripts/install-gate.ts <repo> --check. Install or update it if not.
  3. Run the gate over the whole repository: node scripts/check-plugin-safety.ts .. Comments, documents and generated files count.
  4. Validate: claude plugin validate <plugin-root> --strict.
  5. Fix every hit in one pass, then run steps 3 and 4 again. Each extra round is an upload.
  6. Bump the version, tag if the plugin ships release assets, and upload.
  7. Read the report with the report reader. Paste only the diagnostics array, never the whole report.

The scripts

Plain Node 22.6 or later, no dependencies, run as node scripts/<name>.ts.

check-plugin-safety.ts

The gate. Takes one or more roots (default .); prints one line per problem and exits 1 if there are any.

install-gate.ts

node scripts/install-gate.ts <repo>           install or update the gate; add the CI workflow if missing
node scripts/install-gate.ts <repo> --check   report drift only; exit 1 if anything is missing or old
node scripts/install-gate.ts <repo> --force   also overwrite a workflow that differs from the template

read-report.ts

node scripts/read-report.ts report.json

Prints the phases, each hold or blocking finding, the file the scan named, and the readable files that sort before it. Exits 1 on a hold.

make-probe.ts

node scripts/make-probe.ts round1  <file> <outDir> [slices]
node scripts/make-probe.ts narrow  <outDir> <slice> [slices]
node scripts/make-probe.ts windows <outDir> <slice>
node scripts/make-probe.ts explain <outDir> <reported-file>

How the scan behaves

What held a real plugin

What matchesWhat to do
A plugin name within two edits of a directory name, or the same words reorderedChoose a long, descriptive name and compare it with the public catalog names. The display name does not count.
A script or document of 256 KiB or moreSplit vendored code into readable files under the limit.
One word longer than about 4 KiBSplit the string literal with concatenation.
A shell command that prints the environment, alone in a call or a conditionRewrite the call or the variable. Never spell it in prose, comments or documents.
A template placeholder whose expression names a credentialRename it, or build the string by concatenation.
Prose that reads as a shell lineReword. Strip comments from vendored bundles.
A glob in a document that covers images or fontsUse a path with no images under it.
A remote host and an environment reference in one fileMove one of them.
A native executable in the repositoryShip source and fetch a pinned build.
A list of plain English words joined with pipes, when one word is a command wordBuild the list from an array and join it.
The whole environment used as a value, in a test file or a commentRead named variables. Describe the shape in words.
A script that names an image or a font that exists in the repositoryUse a name that no file in the repository has. A document naming it is fine.

Pinning a hold with the probe

  1. Run round1 on the file the finding names. It writes a small plugin whose probe/ holds 16 slices.
  2. Push that folder to a throwaway public repository and upload it.
  3. The finding names a slice. Run narrow on it, push, upload.
  4. At a few lines, run windows. The smallest window that triggers shows how many lines the trigger needs. explain prints the original lines.
  5. Fix every instance of that shape in the real plugin, upload it, and delete the probe repository.

Bundling third-party code

Keep each bundled file under 256 KiB and readable. Strip comments from vendored bundles, split long string literals, rewrite calls and variables that read as lone command words, and neutralize credential-named placeholders. Make each build-time transform fail the build if its target text is not found, so a dependency upgrade cannot silently undo it.

FAQ

Is the gate the real scan? No. It is built from observed behavior. A clean run does not guarantee a clean report, and a hit may not hold in the real scan.

What if only false positives remain? A hold goes to a human reviewer. Use the portal's help action with a short note: what the plugin does and which file matches.

Does it send anything anywhere? No. The scripts read the directory you point them at and write only where you tell them to.