From m
Package skills, agents, commands into a Claude Code plugin from natural language instructions
npx claudepluginhub ai-builder-team/ai-builder-plugin-marketplace --plugin mThis skill uses the workspace's default tool permissions.
You are packaging Claude Code skills, agents, commands, hooks, and other assets from a source directory into a properly structured Claude Code plugin.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
You are packaging Claude Code skills, agents, commands, hooks, and other assets from a source directory into a properly structured Claude Code plugin.
The user said:
$ARGUMENTS
Decide which path to follow before doing anything else:
Custom objective: If the user's instruction asks for something other than packaging components into a plugin (e.g. inspecting a plugin's structure, updating a single field in plugin.json, comparing versions, listing components, debugging a plugin install issue), then use the plugin structure knowledge, naming conventions, and rules documented below to achieve their objective directly. You are not bound to the packaging workflow — treat the steps and rules as reference material.
Standard packaging (default when the instruction describes components to package, or mentions "package", "bundle", "create plugin", "update plugin"): Follow Steps 0–6 below in sequence.
Parse the user's natural language request to extract:
.claude/ directory, a standalone folder, or any path. If not mentioned, default to .claude/ in the current project./plugin-name:command). If not mentioned, infer from the source directory name or the dominant component names.~/.claude/skills/ or ~/.claude/agents/, that's a personal component. List the existing plugins in the marketplace and see if one already belongs to the same user. Match by username in the path, plugin author, or existing skill patterns. If a match is found, the target is that plugin's directory (e.g., ./plugins/munawar/skills/<skill-name>), not a new standalone plugin. If no match is found or ownership is genuinely unclear, ask the user: "Should this go into an existing plugin or a new standalone one?" Only default to ./plugins/<plugin-name> when you're confident it's a new plugin with no existing home.If something critical is ambiguous (e.g., the source directory could be multiple things, or it's unclear whether this belongs to an existing plugin), ask the user before proceeding. Do NOT guess when the answer matters — a wrong target directory means rework.
Read the source directory and catalog what exists:
source/
├── agents/*.md
├── commands/*.md
├── skills/*/SKILL.md
├── hooks/ (hooks.json or individual configs)
├── scripts/
├── templates/
├── tests/
└── .mcp.json (if present)
List each component found with a count. If a component filter was specified, apply it. If the source directory doesn't exist or has no recognizable components, stop and tell the user.
Check if <target>/.claude-plugin/plugin.json already exists.
If it does NOT exist (fresh package): set version to 1.0.0.
If it DOES exist (update): read it and extract the current version, then determine what changed:
Catalog the source (from Step 1) — build a set of source component names:
source/skills/.md) under source/agents/.md) under source/commands/Catalog the existing target — build the same set from the current plugin:
<target>/skills/.md) under <target>/agents/.md) under <target>/commands/Diff the two sets:
added = names in source but NOT in target (new components)updated = names in BOTH source and target (existing components being overwritten)removed = names in target but NOT in source (only relevant if user asked to remove stale components)Discover naming conventions (for updated components):
Source and target may use different naming patterns. The plugin's names are the canonical ones — source names must be mapped to match them during the copy.
For each updated component, compare the source name to the target name and detect any systematic transform:
m-bugfix.md → target has bugfix.md (prefix m- was stripped)bugfix.md → target has m-bugfix.md (prefix m- was added)m-bugfix.md → target has munawar-bugfix.md (prefix changed)How to detect:
a. For each matched pair in updated, check if the source name and target name differ only by a prefix (everything before the first - or _).
b. If a consistent prefix transform applies to all or most matched pairs, record it as the naming convention.
c. Print the discovered convention:
Naming convention detected:
Source prefix: "m-" → Target prefix: "" (stripped)
Applies to: 8/8 matched components
d. For added components (new ones), apply the same transform so they follow the plugin's existing pattern. For example, if source has m-new-skill and the convention strips m-, the target name becomes new-skill.
e. If no consistent pattern is found (mixed naming), print a warning and keep source names as-is.
Decide the bump:
added is non-empty (new skills, agents, or commands were introduced) → Minor bump (e.g. 1.2.0 → 1.3.0)added is empty but updated is non-empty and changes are large refactors → Minor bump (e.g. 1.2.0 → 1.3.0)added is empty and changes are routine edits to existing components → Patch bump (e.g. 1.2.0 → 1.2.1)1.2.0 → 2.0.0)Print the version decision before proceeding:
Existing plugin version: 1.2.0
New components: skill/foo, agent/bar (or "none")
Updated components: skill/baz, agent/qux (or "none")
Version bump: MAJOR → 2.0.0 (or MINOR → 1.3.0)
If the user specified an explicit version, skip this logic and use their version.
Create the target directory with the correct plugin layout:
mkdir -p <target>/.claude-plugin
IMPORTANT: If Step 1.5 discovered a naming convention, apply it during the copy. Rename files/directories from source names to their target-convention names. For example, if the convention strips prefix m-, then source/agents/m-bugfix.md copies to <target>/agents/bugfix.md, and source/skills/m-locator/ copies to <target>/skills/locator/.
For each component type found (respecting any filter):
*.md files to <target>/agents/ (applying name transform)*.md files to <target>/commands/ (applying name transform)SKILL.md plus any guidelines/, templates/, scripts/ subdirectories) to <target>/skills/ (applying name transform to the directory name)hooks.json exists, copy to <target>/hooks/hooks.json. If hooks are in a settings file, extract the hooks object and write it to <target>/hooks/hooks.json.<target>/scripts/ and ensure shell scripts are executable (chmod +x)<target>/templates/<target>/tests/<target>/.mcp.jsonUse cp -r to preserve directory structure. Only use mv if the user explicitly asked to move/migrate.
Write <target>/.claude-plugin/plugin.json using the version computed in Step 1.5:
{
"name": "<plugin-name>",
"description": "<description>",
"version": "<version-from-step-1.5>",
"author": {
"name": "<author>"
},
"keywords": [<generated-from-contents>]
}
Generate keywords from the component names (e.g., skill names, agent names). Keep it to 5-8 relevant tags.
If the user wants marketplace registration:
Read <marketplace>/.claude-plugin/marketplace.json
Compute the relative source path from the marketplace root to the plugin directory (must start with ./)
Search the plugins array for an existing entry with the same "name":
If the plugin already exists in the array: update the existing entry's version, description, and tags fields to match the new values. Do NOT add a duplicate entry.
If the plugin does NOT exist in the array: add a new entry:
{
"name": "<plugin-name>",
"source": "./<relative-path-to-plugin>",
"description": "<description>",
"version": "<version-from-step-1.5>",
"category": "development",
"tags": [<keywords>]
}
marketplace.json back. The version in the marketplace entry MUST match the version in plugin.json — both come from Step 1.5.If the marketplace.json does NOT exist yet but the user wants marketplace registration, create the full marketplace structure:
{
"name": "<derive-from-directory-name>",
"owner": {
"name": "<author or 'Team'>"
},
"metadata": {
"description": "<marketplace description>",
"version": "1.0.0",
"pluginRoot": "./plugins"
},
"plugins": [
{ <the new plugin entry> }
]
}
After all operations:
find <target> -maxdepth 3 | sort to show the created structure.claude-plugin/plugin.json is valid JSONmarketplace.json is valid JSON1.0.0, major, minor, or patch bump)claude --plugin-dir <target>/plugin marketplace add <marketplace-path> then /plugin install <name>@<marketplace-name>plugin.json goes inside .claude-plugin/. All component directories (agents/, commands/, skills/, hooks/) must be at the plugin root level.SKILL.md (exact filename) inside a named subdirectory..md files in the commands/ directory..md files in the agents/ directory.hooks/hooks.json, not inside .claude-plugin/.${CLAUDE_PLUGIN_ROOT} for portability. If you find hardcoded absolute paths in hook commands or MCP server configs during the copy, replace them with ${CLAUDE_PLUGIN_ROOT}/... relative equivalents.~/.claude/skills/..., ~/.claude/scripts/..., or any absolute path. Replace them with ${CLAUDE_PLUGIN_ROOT}/... equivalents. This applies to bash commands in skills, script references in agents, and any path a user might have written for personal use that now needs to be portable.cp (copy). Only use mv (migrate) if the user explicitly asks to move/migrate. If moving, remove the source directory afterward only if fully emptied.settings.json, settings.local.json, or CLAUDE.md, do NOT copy/move those -- they are project config, not plugin components. Leave them in place.SKILL.md frontmatter name: field must be prefixed with <plugin-name>: where <plugin-name> is the name field from the plugin's plugin.json (e.g., if plugin.json has "name": "m", then skills are m:skill-name; if "name": "klair-legacy", then klair-legacy:skill-name). During packaging, read plugin.json to get the plugin name, then check each skill's name: field — if the prefix is missing, add it. This ensures skills are namespaced correctly when installed.Never edit files under ~/.claude/plugins/cache/ — that's a read-only installed copy.
To find the editable source, first figure out what kind of repo you're in. If the CWD path or directory name contains "plugin", "skills", or "marketplace", or there's a skills/ directory with skill folders in it, you're likely in a plugin or skills repo — search plugins/*/skills/*/SKILL.md and skills/*/SKILL.md relative to the repo root. If not found, check these fallbacks:
~/.claude/skills/<skill-name>/SKILL.md<project-root>/.claude/skills/<skill-name>/SKILL.mdAfter editing files in a marketplace git repo (whether through standard packaging or the custom objective path):
Bump the plugin version in both plugin.json and the corresponding marketplace.json entry:
4.3.0 → 4.3.1)4.3.0 → 4.4.0)4.3.0 → 5.0.0)Push changes — run /m:push from the repo root to commit and push.