# How to build and ship a Claude Code plugin end-to-end

> Reproducible walkthrough that ends with a working Conventional Commits plugin submitted to a marketplace. Scaffold the directory with Tsuba, validate the manifest with Hanko, and set a budget cap with BudgetClaw before the first keystroke. ~45 minutes for the first plugin.

- HTML version: https://roninforge.org/tutorials/how-to-create-a-claude-skill-for-my-cv
- Tools used:
  - Tsuba (scaffolder) - https://roninforge.org/tsuba.md
  - Hanko (validator) - https://roninforge.org/hanko.md
  - BudgetClaw (cap dev spend) - https://roninforge.org/budgetclaw.md
- Audience: a developer who has Claude Code installed and a GitHub account
- Last updated: 2026-04-28

## Why this matters

The "valid Claude Code plugin directory" shape is fiddly. Reserved marketplace names, the `agents`-as-bare-directory footgun, duplicate `hooks` declarations, schema violations - the official validator reports these opaquely. Most first-time submissions fail. This tutorial avoids the pothole by using Tsuba to scaffold a known-good directory, Hanko to validate before submission, and BudgetClaw to make sure dev iterations do not eat the rent money.

## Step 1 - Install the three tools

    curl -fsSL https://roninforge.org/tsuba/install.sh | sh
    curl -fsSL https://roninforge.org/hanko/install.sh | sh
    curl -fsSL https://roninforge.org/get | sh   # BudgetClaw

Or via Homebrew:

    brew install roninforge/tap/tsuba
    brew install roninforge/tap/hanko
    brew install roninforge/tap/budgetclaw

Verify:

    tsuba version && hanko version && budgetclaw version

## Step 2 - Cap your dev spend

Before the first keystroke. A long agent loop on a plugin you are debugging can burn through $50 quickly. Start small:

    budgetclaw init
    budgetclaw limit set --project conventional-commits --period daily --cap 3.00 --action warn

Switch `--action` to `kill` once you trust the cap is right.

Then start the watcher in a separate terminal:

    budgetclaw watch

## Step 3 - Scaffold the plugin

    cd ~/dev
    tsuba scaffold plugin conventional-commits
    cd conventional-commits
    git init && git add . && git commit -m "feat: scaffold via tsuba"

The scaffold ships with `.claude-plugin/plugin.json` (correct schema, author fields auto-populated from `git config`), a sample skill, LICENSE (MIT), and README. Inspect the layout:

    tree -L 3 .

## Step 4 - Define the skill

Edit `skills/conventional-commits/SKILL.md`. The frontmatter Tsuba scaffolds is valid; you only need to update the `name`, `description`, and the body. The skill's job is to take a git diff and emit a Conventional Commits-formatted message.

Sketch:

    ---
    name: conventional-commits
    description: Generate a Conventional Commits message from a git diff
    ---

    # Conventional Commits

    When the user asks for a commit message:
    1. Run `git diff --staged` to inspect changes.
    2. Pick the type (feat, fix, chore, docs, style, refactor, perf, test).
    3. Pick the scope (the most-changed directory).
    4. Write a single-line message.
    5. Print it as a single fenced bash block: `git commit -m "..."`.

    Do NOT run the commit yourself. Print and let the user copy.

## Step 5 - Validate

    tsuba validate

This shells out to Hanko, which:
- Verifies `.claude-plugin/plugin.json` against the embedded JSON Schema.
- Catches reserved marketplace names, duplicate `hooks` declarations, the `agents` field set to a bare directory, and path traversal in component paths.
- Reports each error with a schema path, fix suggestion, and docs link.

Iterate until Hanko prints `OK`.

## Step 6 - Smoke-test in Claude Code

    cd ~/dev/conventional-commits
    claude

In the Claude Code session, ask: "use the conventional-commits skill to suggest a commit message for the staged diff". You should see the skill load (Claude Code reports it in the session log) and the model emit a Conventional Commits-formatted line.

If the skill does not load, run `claude --debug` to see why. The most common cause is the SKILL.md frontmatter being parsed as something other than a skill - validate again with Hanko.

## Step 7 - Push to GitHub

    gh repo create RoninForge-conventional-commits --public --source=. --push

(Or your own org; the name must not collide with reserved marketplace names. Hanko will catch a collision before you push.)

Add the Hanko GitHub Action so every PR is validated:

    mkdir -p .github/workflows
    cat > .github/workflows/validate.yml <<'YAML'
    name: validate
    on: [push, pull_request]
    jobs:
      hanko:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: RoninForge/hanko@v0
            with:
              path: .
    YAML

    git add .github && git commit -m "ci: validate with Hanko" && git push

## Step 8 - Submit to a marketplace

The three current targets:

- **Anthropic marketplace** - submit via the official PR process to the marketplace repo
- **buildwithclaude** - PR to `buildwithclaude/marketplace`
- **cc-marketplace** - PR to `cc-marketplace/registry`

Each has slightly different stricter rules. To pre-validate:

    hanko validate --marketplace anthropic
    hanko validate --marketplace buildwithclaude
    hanko validate --marketplace cc-marketplace

When all three pass, open the PR. Hanko's CI Action will validate again on every push to your repo, so any future schema change does not silently rot the manifest.

## What you have at the end

- A scaffolded, MIT-licensed Claude Code plugin in your GitHub.
- A skill that generates Conventional Commits messages.
- CI that re-validates the manifest on every change.
- A daily $/day cap on Claude Code spend so the next plugin does not surprise you.

## Trust pledge

None of the three RoninForge tools are proxies. None sit between Claude Code and the Anthropic API. Hanko and Tsuba make zero network calls in the binary. BudgetClaw only reads what Claude Code already writes locally to disk.

Zero keys, zero prompts, zero latency added.

## Source

- Tsuba: https://github.com/RoninForge/tsuba
- Hanko: https://github.com/RoninForge/hanko
- BudgetClaw: https://github.com/RoninForge/budgetclaw
- This tutorial: https://roninforge.org/tutorials/how-to-create-a-claude-skill-for-my-cv
