Claude-kit plugin-generator
Generate a Claude Code plugin package from the current project's dotforge configuration, ready for marketplace submission.
install
source · Clone the upstream repo
git clone https://github.com/luiseiman/dotforge
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/luiseiman/dotforge "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/plugin-generator" ~/.claude/skills/luiseiman-claude-kit-plugin-generator && rm -rf "$T"
manifest:
skills/plugin-generator/SKILL.mdsource content
Plugin Generator
Generate a distributable Claude Code plugin from the current project's dotforge configuration. The output is a standalone directory ready for
claude --plugin-dir testing or marketplace submission.
Input
$ARGUMENTS may contain:
- Output directory path (default:
)./dotforge-plugin/
to override plugin name (default: project directory name)--name <name>
Step 1: Validate source
Verify the current project has dotforge configuration:
must existCLAUDE.md
must exist.claude/settings.json
should exist (warn if missing).claude/rules/
If missing, error: "No dotforge configuration found. Run
/forge bootstrap first."
Step 2: Detect components
Scan the project's
.claude/ directory and catalog:
Component scan: CLAUDE.md → will become commands/context.md .claude/rules/ → will become skills (one per rule with globs preserved) .claude/hooks/ → will become hooks/hooks.json + script files .claude/commands/ → will become commands/ .claude/agents/ → will become agents/ (if present) .claude/settings.json → will extract deny list → settings.json
Show the scan results and ask for confirmation before generating.
Step 3: Generate plugin structure
Create the output directory with this structure:
{output-dir}/ ├── .claude-plugin/ │ └── plugin.json ├── skills/ │ └── {rule-name}/ │ └── SKILL.md (one per rule, with globs as description context) ├── agents/ (copy from .claude/agents/ if exists) │ └── *.md ├── hooks/ │ ├── hooks.json (converted from settings.json hook wiring) │ └── *.sh (hook scripts) ├── commands/ │ └── *.md (from .claude/commands/) ├── settings.json (deny list only) ├── README.md (auto-generated usage guide) └── LICENSE (copy from project root if exists)
3a. Generate plugin.json
{ "name": "{project-slug}", "version": "1.0.0", "description": "Claude Code plugin generated from {project-name} configuration by dotforge", "author": { "name": "{git user.name or 'Unknown'}" }, "repository": "{git remote origin url or ''}", "license": "{detected license or 'MIT'}", "keywords": ["claude-code", "{stack1}", "{stack2}", "dotforge"] }
3b. Convert hooks
Read
.claude/settings.json hooks section. For each hook entry:
- Copy the .sh script to
hooks/ - Create the corresponding entry in
:hooks/hooks.json
{ "hooks": { "{Event}": [ { "matcher": "{Matcher}", "hooks": [ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/{script-name}.sh" } ] } ] } }
Use
${CLAUDE_PLUGIN_ROOT} for all script paths — this is resolved by Claude Code at runtime.
3c. Convert rules to skills
For each
.claude/rules/*.md:
- Read the frontmatter (globs/paths, description)
- Create
:skills/{rule-name}/SKILL.md
--- name: {rule-name} description: "{description from frontmatter or first heading}" --- {rule content without frontmatter}
3d. Copy agents
If
.claude/agents/ exists, copy all .md files to agents/.
3e. Copy commands
Copy all
.md files from .claude/commands/ to commands/.
3f. Extract settings
From
.claude/settings.json, extract only the deny list into settings.json:
{ "permissions": { "deny": [ "Bash(rm -rf /)", "Read(**/.env)", ... ] } }
Do NOT include allow list or hooks (those are handled by hooks.json).
3g. Generate README.md
# {plugin-name} Claude Code plugin generated by [dotforge](https://github.com/luiseiman/dotforge). ## Install ```bash claude plugin install {plugin-name}@{marketplace}
Or test locally:
claude --plugin-dir ./{output-dir}
Components
- Skills: {N} contextual rules
- Agents: {N} specialized subagents
- Hooks: {N} event handlers (block-destructive, lint, etc.)
- Commands: {N} custom commands
Generated from
- Project: {project-name}
- Stacks: {detected stacks}
- dotforge version: {version}
- Date: {YYYY-MM-DD}
## Step 4: Validate output Run validation on the generated plugin: ```bash # Check plugin.json is valid JSON python3 -c "import json; json.load(open('{output}/plugin.json'))" # Check hooks.json is valid JSON python3 -c "import json; json.load(open('{output}/hooks/hooks.json'))" # Check all .sh files are executable find {output}/hooks -name "*.sh" ! -perm -111 # Check skills have SKILL.md for d in {output}/skills/*/; do ls "$d/SKILL.md"; done
Step 5: Report
═══ PLUGIN GENERATED ═══ Output: {output-dir}/ Name: {plugin-name} Version: 1.0.0 Components: Skills: {N} Agents: {N} Hooks: {N} Commands: {N} ── NEXT STEPS ── 1. Test locally: claude --plugin-dir ./{output-dir} 2. Validate: claude plugin validate ./{output-dir} 3. Submit to marketplace: - Claude.ai: claude.ai/settings/plugins/submit - Console: platform.claude.com/plugins/submit 4. Or distribute via your own marketplace: See https://code.claude.com/docs/en/plugin-marketplaces
Constraints
- NEVER include
,.env
,*.key
, or credentials in the output*.pem - NEVER include
in the outputsettings.local.json - NEVER include
in the output.forge-manifest.json - If the project has a
, respect it when copying files.gitignore - Hook scripts must be
in the outputchmod +x - All paths in hooks.json must use
prefix${CLAUDE_PLUGIN_ROOT}