From official-plugins
This skill should be used when the user asks to "submit my plugin", "publish my plugin", "open a PR for my plugin", "register my plugin", "add to marketplace", "submit to master-plugin-repository", "ship my plugin", "send my plugin to the hackathon", or is ready to send their packaged Claude Code plugin to the OKX hackathon marketplace. Always run package-plugin first to prepare and validate the plugin. Make sure to invoke this skill whenever the user mentions submitting, publishing, PR-ing, or shipping a plugin, even if they don't explicitly say "submit-plugin".
How this skill is triggered — by the user, by Claude, or both
Slash command
/official-plugins:submit-pluginThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the final step in the OKX hackathon submission flow. The participant should already have a packaged plugin directory (typically built by `/official-plugins:package-plugin`). Your job is to validate it one more time, collect the metadata for the marketplace entry, and open a GitHub PR against `mastersamasama/master-plugin-repository` that registers the plugin.
You are the final step in the OKX hackathon submission flow. The participant should already have a packaged plugin directory (typically built by /official-plugins:package-plugin). Your job is to validate it one more time, collect the metadata for the marketplace entry, and open a GitHub PR against mastersamasama/master-plugin-repository that registers the plugin.
This skill is the only path that pushes externally-visible changes. Be conservative. Always confirm before fork, before commit, before push, before PR. Offer dry-run.
Follow this runbook strictly.
Ask the participant for the absolute path to their packaged plugin directory. Call this PLUGIN_DIR.
If PLUGIN_DIR/.package-plugin.state.json exists, read it. It contains the metadata package-plugin already collected — you can pre-fill from it and skip re-asking. Tell the user "I found your package-plugin state file and will pre-fill from it; let me know if anything is wrong."
Verify:
PLUGIN_DIR exists and is a directoryPLUGIN_DIR/.claude-plugin/plugin.json existsIf either check fails, stop and tell the user: "Run /official-plugins:package-plugin first to prepare your plugin." Do not proceed.
This is the only gate between low-quality submissions and the marketplace. Do not skip it. Do not weaken it. Do not let the participant talk you into bypassing it.
Run via Bash:
node ${CLAUDE_PLUGIN_ROOT}/scripts/validate.mjs --plugin <PLUGIN_DIR> --strict --json
The --strict flag turns on the quality gate in addition to the format gate. The combined check covers:
Format gates (always errors):
plugin.json exists, parses, has kebab-case name matching directoryskills/<name>/SKILL.md has YAML frontmatter with matching name..) in any string fieldsource shapes are well-formed (only relevant for --marketplace/--all)Quality gates (errors in --strict, warnings otherwise):
SKILL_DESCRIPTION_MISSING — every skill must have a descriptionSKILL_DESCRIPTION_STYLE — descriptions must follow "This skill should be used when the user asks to ..." (third-person trigger-phrase convention). Vague descriptions undertrigger.SKILL_DESCRIPTION_PLACEHOLDER — {{...}} left unfilled in a SKILL.md descriptionPLUGIN_DESCRIPTION_MISSING — plugin.json must have a descriptionQUALITY_DESCRIPTION_TOO_SHORT — plugin.json description must be ≥ 20 characters (catches "test", "demo", "todo")QUALITY_NO_COMPONENTS — plugin must ship at least one component (skill, command, agent, hook, or MCP server). A plugin with only plugin.json + README is not a plugin.QUALITY_README_MISSING — every plugin must have a README.md at its rootQUALITY_README_NO_NAME — the README must mention the plugin's kebab-case name somewhere (case-insensitive substring match)QUALITY_TEMPLATE_PLACEHOLDER — {{...}} left unfilled in any plugin.json fieldQUALITY_SECRET_PATTERN — files contain a string matching known secret formats (OpenAI/Anthropic API keys, GitHub PATs, AWS keys, Google keys, Slack tokens, JWTs). This is the single most common cause of compliance rejection.Read full reference at references/quality-gates.md for detailed explanation of each.
Parse the JSON output line by line. Each line is one finding with severity, file, line, code, message, why, fix.
If any error severity findings exist (note: in --strict mode, quality issues come back as errors, not warnings):
BLOCKED <file>:<line> [<code>]
<message>
Why: <why>
Fix: <fix>
SUBMISSION BLOCKED — N errors. Fix every error and re-invoke me./official-plugins:package-plugin against <PLUGIN_DIR> to fix these issues with guided edits, then invoke /official-plugins:submit-plugin again."If all findings are warning severity (this should be rare in strict mode — most relevant warnings are promoted to errors):
If clean: print Validation passed: 0 errors, 0 warnings under --strict. and continue to phase 2.
If <PLUGIN_DIR> is a git repository (i.e., <PLUGIN_DIR>/.git exists OR it's nested under one), check for a remote:
cd <PLUGIN_DIR> && git remote get-url origin 2>/dev/null
cd <PLUGIN_DIR> && git rev-parse HEAD 2>/dev/null
Note both for use in phase 3. Don't make assumptions yet — the participant might still want monorepo mode even if they have a remote.
Use AskUserQuestion (single select) with three options:
plugins/<name>/. The PR adds both the plugin files and the marketplace entry. Recommended for plugins that don't need their own repo.".claude-plugin/plugin.json is at the repo root). The PR only adds a marketplace entry pointing at my repo."If you detected a git remote in phase 2, mention it in the description of the external options ("Detected git remote: ").
Read <PLUGIN_DIR>/.claude-plugin/plugin.json and pre-fill:
name ← plugin.json name (do NOT ask — must match)description ← plugin.json descriptionversion ← plugin.json version or 0.1.0author.name ← plugin.json author.namecategory ← plugin.json category or askkeywords ← plugin.json keywords or askShow the participant the pre-filled values and ask: "Anything to change?"
For external modes, additionally collect:
url (the https git URL) and sha (run git rev-parse HEAD if you detected a remote, or ask)url, path (subdirectory), ref (branch/tag, default main), shaAsk the participant: "Do you want a dry run first? I'll build the marketplace entry, validate it against the live marketplace.json (catching duplicate names and other conflicts), show the planned commit message and PR title/body, but stop without forking or pushing anything. Recommended for first-time submitters."
If yes (dry-run mode):
marketplace.json from GitHub via git ls-remote + a sparse clone, or via direct file read if you have a local clone of the marketplace. As a fallback, curl -fsSL https://raw.githubusercontent.com/mastersamasama/master-plugin-repository/main/.claude-plugin/marketplace.json to grab it.--no-source-check because the temp dir won't have the actual plugin subdirectories — that check would false-positive at this stage:
node ${CLAUDE_PLUGIN_ROOT}/scripts/validate.mjs --marketplace <temp-dir> --no-source-check
The validator will catch PLUGIN_NAME_DUPLICATE and any other marketplace-level structural issues.git commit -m message that would be usedmarketplace.json for external modes; that file plus plugins/<name>/... for monorepo mode)If no (real submission), continue to step 6.
Run via Bash:
gh --version
gh auth status
If gh is not installed:
gh auth login and re-invoke this skill. (If you only want a dry-run preview, re-invoke me with dry-run intent — gh isn't needed for that.)"If not authenticated:
gh auth login to authenticate, then re-invoke this skill."Default: ${TEMP}/master-plugin-repository-submit-<plugin-name> on Windows or /tmp/master-plugin-repository-submit-<plugin-name> on unix.
Confirm with the user. Refuse to use a directory that already has a master-plugin-repository clone in it (might be in unknown state) — pick a fresh path.
Run via Bash from the parent of the working directory:
gh repo fork mastersamasama/master-plugin-repository --clone --remote
gh creates the fork under the authenticated user's account and clones it. The clone directory is master-plugin-repository.
cd into the clone.
git checkout -b submit/<plugin-name>
plugins/<plugin-name>/ already exists in the fork — that's a name collision. Tell the user to pick a different plugin name and re-run from package-plugin.<PLUGIN_DIR> contents to plugins/<plugin-name>/. Use cp -r (Unix) or xcopy /E /I /Y (Windows). Show the user the destination tree afterward.{
"name": "<name>",
"description": "<description>",
"version": "<version>",
"author": { "name": "<author.name>" },
"category": "<category>",
"keywords": [...],
"source": "./plugins/<name>"
}
.claude-plugin/marketplace.json, parse it, append to plugins[], write back with 2-space indent + trailing newline.{
"name": "<name>",
"description": "<description>",
"version": "<version>",
"author": { "name": "<author.name>" },
"category": "<category>",
"keywords": [...],
"source": {
"source": "url",
"url": "<url>",
"sha": "<sha>"
}
}
{
"name": "<name>",
"description": "<description>",
"version": "<version>",
"author": { "name": "<author.name>" },
"category": "<category>",
"keywords": [...],
"source": {
"source": "git-subdir",
"url": "<url>",
"path": "<path>",
"ref": "<ref>",
"sha": "<sha>"
}
}
Run the validator inside the clone before committing — once over the whole marketplace, plus once again over the specific plugin in strict mode:
node plugins/official-plugins/scripts/validate.mjs --all
node plugins/official-plugins/scripts/validate.mjs --plugin plugins/<plugin-name> --strict
If errors from either run: stop, report them, do NOT commit. The PR would fail CI anyway. This second validation pass catches issues that may have been introduced by the copy/edit (e.g., a path-traversal that only manifests once the plugin lives at plugins/<name>/ instead of its source location).
Run via Bash:
git diff --stat
git diff
Show the participant the full diff. Get explicit confirmation: "Commit and push these changes? [yes/no]"
git add -A
git commit -m "Add <plugin-name> to marketplace"
git push -u origin submit/<plugin-name>
gh pr create \
--repo mastersamasama/master-plugin-repository \
--base main \
--head <github-username>:submit/<plugin-name> \
--title "Add <plugin-name> to marketplace" \
--body "<body>"
PR body should include:
node plugins/official-plugins/scripts/validate.mjs"Print the PR URL and:
Submission opened. CI will run on your PR within seconds. If CI passes, a reviewer will manually verify and merge. If CI fails, fix the issue locally, push to your
submit/<plugin-name>branch, and the PR will update automatically.If the reviewer requests changes, repeat the package-plugin → submit-plugin loop on a new branch.
gh is installed. Check first.plugins/<name>/ in monorepo mode.references/source-shapes.md — every valid source shape with examples and when to use eachreferences/pr-template-explained.md — what each PR template field means and why it mattersGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub mastersamasama/master-plugin-repository --plugin official-plugins