How to Specify a Plugin Source from a Git Subdirectory in the Claude Plugins Community
Use the git-subdir source type in the manifest's source object and provide the repository URL, relative path, and optional Git ref or pinned SHA to point to a plugin located inside a subdirectory.
The Claude Plugins Community repository (anthropics/claude-plugins-community) manages plugin entries through a centralized manifest system. When your plugin code lives inside a subdirectory rather than at the repository root, you must declare this location using a specific JSON schema that the validation CI recognizes. This guide explains the exact manifest fields and validation logic used to specify a plugin source from a Git subdirectory.
Understanding the git-subdir Source Type
The manifest file (.claude-plugin/marketplace.json) serves as the single source of truth for all community plugins. For plugins not residing at the root of a Git repository, the source object must declare "source": "git-subdir" to signal that the plugin files are nested within a subfolder. This distinction tells the Validate‑Plugins GitHub Action to perform additional path resolution and SHA verification steps during the CI pipeline.
Required Manifest Fields for Git Subdirectory Sources
When configuring a git-subdir entry in the marketplace manifest, include these specific fields:
source: Must be the string"git-subdir"to activate subdirectory mode.url: Either the shorthandowner/repoformat or a full HTTPS URL to the Git repository.path: The directory path relative to the repository root containing the plugin'splugin.jsonorSKILL.md.ref(optional): The Git reference (branch name, tag, or commit) to checkout. Defaults tomainif omitted.sha(optional but recommended): A pinned 40-character commit SHA that the CI validates against the resolved ref to guarantee reproducibility.
How CI Validation Works for Subdirectory Sources
The validation logic resides in .github/actions/validate-plugins/scripts/30-validate-cli-external.sh and executes the following sequence:
- Clones the repository specified in the
urlfield. - Checks out the
ref(or directly uses theshaif provided for verification). - Verifies that the
pathexists within the cloned repository structure. - If a
shais present, confirms that the checkout's HEAD matches the pinned SHA exactly.
If any step fails, the plugin entry is rejected from the marketplace.
Code Examples
Minimal Configuration Without SHA Pinning
Use this approach for development or when you want the plugin to track a moving tag or branch:
{
"name": "example-plugin",
"description": "Demo plugin from a subdirectory",
"source": {
"source": "git-subdir",
"url": "owner/example-repo",
"path": "plugins/example",
"ref": "v2.1.0"
},
"homepage": "https://github.com/owner/example-repo"
}
The CI clones owner/example-repo, fetches tag v2.1.0, and validates that plugins/example exists. Without a sha, the plugin content can change if the tag is moved.
Production Configuration With Pinned SHA
For reproducible builds and security, pin the exact commit hash:
{
"name": "secure-plugin",
"description": "Uses a fixed commit for reproducibility",
"source": {
"source": "git-subdir",
"url": "https://github.com/org/secure-repo.git",
"path": "plugins/secure",
"ref": "main",
"sha": "a1b2c3d4e5f67890123456789abcdef012345678"
},
"homepage": "https://github.com/org/secure-repo"
}
The validation script checks out main, then verifies that the HEAD commit matches a1b2c3d4e5f67890123456789abcdef012345678 before accepting the subdirectory content.
Validating Locally Before Submission
Mirror the CI checks locally using the validation script to catch errors early:
# Run the same validation logic used by the GitHub Action
bash .github/actions/validate-plugins/scripts/30-validate-cli-external.sh \
--name example-plugin \
--source "$(cat entry.json)"
This script uses helper utilities from .github/actions/validate-plugins/lib/common.sh (including path safety checks) to ensure your git-subdir configuration is valid before pushing to the repository.
Key Source Files in the Repository
Understanding these files helps when debugging subdirectory configuration issues:
.claude-plugin/marketplace.json: The central manifest wheregit-subdirentries are registered (see lines 57‑84 for examples)..github/actions/validate-plugins/scripts/30-validate-cli-external.sh: The CI script that handles cloning, ref resolution, and SHA verification for subdirectory sources..github/actions/validate-plugins/lib/common.sh: Provides utility functions likeassert_safe_pathused during validation..github/actions/bump-plugin-shas/scripts/bump.sh: Automates updating pinned SHAs forgit-subdirentries during release workflows.
Summary
- Set
"source": "git-subdir"in the manifest to indicate a subdirectory location. - Provide the repository
urland relativepathto the plugin files. - Use the
reffield to specify a branch or tag, defaulting tomain. - Pin a
shafor reproducible builds and enhanced security. - The CI validation enforces existence of the path and SHA/ref consistency before accepting entries.
Frequently Asked Questions
What happens if the path does not exist in the repository?
The Validate‑Plugins action rejects the entry. Specifically, the script 30-validate-cli-external.sh verifies path existence after cloning, and if the subdirectory is missing, the validation fails with an error message indicating the path was not found.
Can I use a private Git repository as a git-subdir source?
The current implementation in the anthropics/claude-plugins-community repository assumes public repositories accessible via HTTPS. The validation scripts do not include authentication logic for private repositories in the standard CI workflow.
How do I update the pinned SHA for my plugin?
Use the automated bump workflow or manually edit the sha field in .claude-plugin/marketplace.json. The bump.sh script (located at .github/actions/bump-plugin-shas/scripts/bump.sh) can automatically fetch the latest commit from your specified ref and update the SHA field to maintain reproducibility while pulling in updates.
Is the ref field required if I provide a SHA?
No, the ref field is optional, but providing it improves readability and ensures the CI checks out the correct branch before verifying the SHA. If omitted, the validation defaults to main, which may cause failures if your pinned SHA exists only on a different branch.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →