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.md
source 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/
    )
  • --name <name>
    to override plugin name (default: project directory name)

Step 1: Validate source

Verify the current project has dotforge configuration:

  • CLAUDE.md
    must exist
  • .claude/settings.json
    must exist
  • .claude/rules/
    should exist (warn if missing)

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:

  1. Copy the .sh script to
    hooks/
  2. 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
:

  1. Read the frontmatter (globs/paths, description)
  2. 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
    ,
    *.pem
    , or credentials in the output
  • NEVER include
    settings.local.json
    in the output
  • NEVER include
    .forge-manifest.json
    in the output
  • If the project has a
    .gitignore
    , respect it when copying files
  • Hook scripts must be
    chmod +x
    in the output
  • All paths in hooks.json must use
    ${CLAUDE_PLUGIN_ROOT}
    prefix