A small TUI + CLI to manage the three Claude Code plugin repositories as a unit:
- npm-registry-manager (plugin)
- npm-package-owner (plugin)
- claude-marketplace (catalog)
Built with Cobra + Bubble Tea + Lipgloss. Run it with no arguments for an interactive TUI, or use subcommands for scripting.
These three repos move together. A version bump to a plugin has to be reflected in two files — the plugin's own plugin.json and the matching entry in the marketplace catalog's marketplace.json. Doing that by hand is exactly the kind of error-prone, easy-to-forget step that drifts. ccpm does it in one command, with a confirmation, and validates the JSON stays intact.
It also batches the boring stuff — status / pull / push / commit across all three at once — and handles release tagging.
go install github.com/RonenMars/ccpm@latestOr build from source:
git clone https://github.com/RonenMars/ccpm
cd ccpm
go build -o ccpm .
# move ccpm onto your PATHResolution order, per repo:
- Config override — explicit path in
~/.config/ccpm/config.json - Auto-discovery — a sibling directory of the
ccpmbinary, or a sibling of your current working directory / its parent
In the common case where all four repos (the three managed + ccpm) share a parent directory, auto-discovery just works with zero setup.
Set an explicit path:
ccpm config --set npm-registry-manager=/abs/path/to/npm-registry-managerShow what it found:
ccpm configccpm| Key | Action |
|---|---|
↑/↓ (j/k) |
Move selection |
r |
Refresh git status |
p |
Pull all (--ff-only) |
P |
Push all |
c |
Commit (prompts for a message; applies to dirty repos) |
b |
Bump selected plugin's version (patch/minor/major) — updates plugin.json and the catalog |
t |
Tag/release selected plugin (vX.Y.Z) and push the tag |
q |
Quit |
The bump and release actions show a confirmation before doing anything.
ccpm status # git status of all three
ccpm pull # git pull --ff-only on all
ccpm push # git push on all
ccpm commit "message" # stage+commit dirty repos
ccpm bump npm-package-owner minor # bump version in plugin.json + catalog
ccpm release npm-package-owner # tag vX.Y.Z and push
ccpm config # show resolved paths
ccpm config --set name=/path # override a pathAdd --yes / -y to bump and release to skip the confirmation (for scripts/CI).
This is the reason the tool exists. When you run:
ccpm bump npm-registry-manager patchit:
- Reads the current version from
npm-registry-manager/.claude-plugin/plugin.json - Computes the next version (semver-aware; strips any prerelease suffix for the calc)
- Shows a plan and asks for confirmation
- On confirm, surgically edits two files:
- the plugin's
plugin.jsonversion - the matching plugin entry's
versioninsideclaude-marketplace/.claude-plugin/marketplace.json
- the plugin's
- Validates both files are still valid JSON before writing
The edits are string-level and key-order-preserving, so diffs are exactly one line per file — no reformatting noise, and no risk of reordering keys. Other plugins' entries in the catalog are left untouched.
ccpm bump npm-package-owner patch # 0.2.0 -> 0.2.1 in both files
ccpm commit "chore: release npm-package-owner 0.2.1"
ccpm push
ccpm release npm-package-owner # tag v0.2.1, push tagpulluses--ff-onlyto avoid surprise merge commits.commitskips clean repos automatically.releaserefuses if the tag already exists, so it's safe to re-run.- All git operations shell out to your system
git, so your existing config, credentials, and hooks apply.
MIT