--- name: managing-marketplaces description: Use when working with Claude Code plugin marketplaces - adding, updating, creating, or understanding how marketplace versioning and caching work. --- # Managing Marketplaces ## Overview Plugin marketplaces are catalogs of available plugins. This skill covers how updates work, caching, and versioning. ## Key Locations | Path | Purpose | |------|---------| | `~/.claude/plugins/marketplaces/` | Git clones of remote marketplaces | | `~/.claude/plugins/cache////` | Cached plugin versions | | `~/.claude/plugins/known_marketplaces.json` | Marketplace registry with update timestamps | ## Update Mechanism ### Marketplace Level (No Version Pin) Marketplaces track **main branch HEAD** - no commit pinning: ```json // known_marketplaces.json { "superpowers-marketplace": { "source": { "source": "git", "url": "https://github.com/obra/superpowers-marketplace.git" }, "lastUpdated": "2026-01-09T15:25:06.447Z", "autoUpdate": true } } ``` - `autoUpdate: true` pulls latest on startup/refresh ### Plugin Level (Version Pinned) Plugins ARE versioned via the `version` field in plugin.json: ``` ~/.claude/plugins/cache/ ├── superpowers-marketplace/ │ └── superpowers/ │ └── 4.0.3/ ← version from plugin.json └── claude-plugins-official/ └── hookify/ └── e30768372b41/ ← commit hash for official plugins ``` ### Update Flow ```dot digraph update_flow { rankdir=TB; "Claude Code starts" [shape=box]; "Pull marketplace (git pull main)" [shape=box]; "Read marketplace.json" [shape=box]; "For each enabled plugin" [shape=diamond]; "Check if version cached" [shape=diamond]; "Use cached version" [shape=box]; "Fetch plugin from source" [shape=box]; "Cache at version directory" [shape=box]; "Claude Code starts" -> "Pull marketplace (git pull main)"; "Pull marketplace (git pull main)" -> "Read marketplace.json"; "Read marketplace.json" -> "For each enabled plugin"; "For each enabled plugin" -> "Check if version cached"; "Check if version cached" -> "Use cached version" [label="yes"]; "Check if version cached" -> "Fetch plugin from source" [label="no"]; "Fetch plugin from source" -> "Cache at version directory"; "Cache at version directory" -> "For each enabled plugin"; "Use cached version" -> "For each enabled plugin"; } ``` ## Version Pinning Summary | Layer | Pinned? | Update Mechanism | |-------|---------|------------------| | Marketplace | No (tracks main HEAD) | `autoUpdate: true` or `/plugin marketplace update` | | Plugin | Yes (version field) | Bump version in plugin.json → new cache dir | ## Commands ```bash # List known marketplaces /plugin marketplace list # Update marketplace metadata /plugin marketplace update # Add marketplace /plugin marketplace add owner/repo # GitHub /plugin marketplace add ./local-path # Local /plugin marketplace add https://url.git # Git URL # Remove marketplace (also uninstalls plugins from it) /plugin marketplace remove ``` ## Local Development ### ccd CLI (Recommended) For marketplaces with a CLI for managing symlinks, use it: ```bash cd ~/projects/my-marketplace pnpm install pnpm ccd link activate # Symlink all plugins (creates cache if needed) pnpm ccd link review # Check status pnpm ccd link deactivate # Remove symlinks ``` Run `pnpm ccd --help` for full documentation including path resolution diagrams. **Workflow:** 1. Activate symlinks: `pnpm ccd link activate` (no install required) 2. Develop: edit source, restart CC to see changes 3. Relink after any `claude plugin install` (overwrites symlinks) ### Manual Symlink Method For marketplaces without the CLI, manually replace cache with symlinks. **Key insight:** Cache path uses marketplace's `name` field from marketplace.json, not the source (GitHub vs local). So `~/.claude/plugins/cache//...` is the same whether you installed from GitHub or local path. ```bash # 1. Clone repo locally (if not already) git clone https://github.com/owner/marketplace ~/projects/my-marketplace # 2. If not installed, add and install (skip if already from GitHub) claude plugin marketplace add ~/projects/my-marketplace claude plugin install my-plugin@my-marketplace # 3. Replace cache with symlink (works for GitHub or local installs) rm -rf ~/.claude/plugins/cache//my-plugin/*/ ln -s ~/projects/my-marketplace/plugins/my-plugin \ ~/.claude/plugins/cache//my-plugin/ ``` **Caveats:** - Reinstall overwrites symlink - re-run step 3 after any install - Session-based reload, not hot-reload in same session **Why this works:** CC loads plugins from cache path. Symlink makes cache path point to source. CC follows symlinks transparently. ### Standard Method [Official docs](https://docs.claude.com/en/docs/claude-code/plugins#test-your-plugins-locally) show uninstall/reinstall cycle: ```bash /plugin uninstall my-plugin@my-marketplace /plugin install my-plugin@my-marketplace ``` ## Enabling Plugins In project or user `settings.json`: ```json { "enabledPlugins": { "plugin-name@marketplace-name": true } } ``` ## Creating Plugins in a Marketplace **CRITICAL**: When creating a new plugin, you MUST do BOTH: 1. Create the plugin directory with `plugin.json` 2. Register the plugin in `marketplace.json` ``` marketplace/ ├── .claude-plugin/ │ └── marketplace.json ← MUST add entry here └── plugins/ └── new-plugin/ └── plugin.json ← AND create this ``` **Failure mode**: Creating only the directory results in `/doctor` errors like: ``` Plugin new-plugin not found in marketplace marketplace-name ``` ### Checklist for New Plugin - [ ] Create `plugins//plugin.json` with name, version, description - [ ] Add entry to `.claude-plugin/marketplace.json` plugins array - [ ] Entry must include: `name`, `source` (e.g., `"./plugins/"`), `description` - [ ] Run `/doctor` to verify no plugin errors ## Notes - Removing a marketplace uninstalls all plugins from it - Multiple versions can coexist in cache (old versions not auto-cleaned) - `lastUpdated` timestamp tracks when marketplace was last refreshed