From marketplace-ops
Process /save and /drop comments on a pruning PR, restore or remove items, and update .pruneprotect
How this command is triggered — by the user, by Claude, or both
Slash command
/marketplace-ops:prune-update [PR number or URL]Files this command reads when invoked
The summary Claude sees in its command listing — used to decide when to auto-load this command
## Name marketplace-ops:prune-update ## Synopsis ## Description Reads comments on a pruning PR to find `/save <path>` and `/drop <path>` directives. For each **saved** item: 1. Restores the files from the base branch. 2. Adds the path to `.pruneprotect` permanently, with a comment noting who requested it and when. 3. Pushes a new commit to the PR branch (never force-pushes). 4. Updates the PR body to mark saved items. For each **dropped** item: 1. If the item was previously `/save`d: removes its files again, removes it from `.pruneprotect`. 2. If the item is a new addition (not in the ...
marketplace-ops:prune-update
/marketplace-ops:prune-update [PR number or URL]
Reads comments on a pruning PR to find /save <path> and /drop <path> directives.
For each saved item:
.pruneprotect permanently, with a comment noting who requested it and when.For each dropped item:
/saved: removes its files again, removes it from .pruneprotect.plugin.json.$1: (Optional) PR number or URL. If omitted, searches for the most recent open pruning PR by the current user.If a PR number or URL was provided, use it directly. Otherwise, find the most recent open pruning PR:
gh pr list --author="@me" --state=open --search="prune stale marketplace" --json number,title,url,headRefName --limit 5
Select the first result. If no pruning PR is found, report this to the user and stop.
Fetch all comments on the PR (both issue comments and review comments), including the author's association to the repository:
# Issue comments
gh api repos/{owner}/{repo}/issues/{pr_number}/comments \
--jq '.[] | {id: .id, created_at: .created_at, author: .user.login, association: .author_association, body: .body}'
# Review comments
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
--jq '.[] | {id: .id, created_at: .created_at, author: .user.login, association: .author_association, body: .body}'
Parse each comment body for lines matching /save <path> or /drop [--force] <path>. The --force flag is optional and only valid on /drop directives. Only accept directives from trusted participants — those with author_association of OWNER, MEMBER, or COLLABORATOR. Skip directives from other associations and log a warning (e.g., "Ignoring /drop --force from @user — not a repository collaborator").
For each accepted match, record:
save or drop)force flag (true if --force was present, false otherwise)Deduplicate paths. If a path has both /save and /drop from different comments, the latest comment wins (last-writer-wins): sort all collected directives by created_at ascending, using id as a tiebreaker for comments with identical timestamps, so the newest directive for a given path takes precedence. If no valid directives are found, report this and stop.
For /save paths: Cross-reference against the removal manifest table in the PR body. The path must appear in the manifest (and not already be marked [SAVED]) — if it does not, it was either already saved, was not part of this pruning cycle, or is a typo. Report invalid paths to the user but continue processing valid ones.
For /drop paths — two valid cases:
[SAVED] strikethrough markup. This reverses the save..pruneprotect — if it is, warn that the item is protected and skip it unless the directive's force flag is true (i.e., the commenter used /drop --force plugins/foo/).Report paths that fail validation but continue processing valid ones.
gh pr checkout {pr_number}
Get the base branch from the PR:
base_branch=$(gh pr view {pr_number} --json baseRefName --jq '.baseRefName')
For each valid /save path, restore from the base branch:
git checkout {upstream_remote}/{base_branch} -- {path}
Use the upstream remote (not origin) to ensure the base branch is current.
For each valid /drop path:
If undoing a previous save:
# Full plugin removal
git rm -rf {path}
# Individual file removal
git rm {path}
.pruneprotect (including its comment line).If adding a new drop:
git rm commands as above).plugins/{plugin-name}/.claude-plugin/plugin.json (e.g., 0.0.5 → 0.0.6).For /save items: append each saved path to .pruneprotect with a comment indicating who requested the save:
# Saved by @username on 2026-05-05
plugins/foo/
For /drop items that undo a save: remove the path and its comment from .pruneprotect.
If .pruneprotect does not exist, create it with the saved entries.
Run make update to regenerate marketplace.json and docs after changes:
make update
git add -A
Create a new commit (never amend, never force-push):
git commit -m "$(cat <<'EOF'
chore: process save/drop directives from pruning PR
Restored and added to .pruneprotect:
- plugins/foo/ — saved by @username
Dropped:
- plugins/bar/commands/baz.md — dropped by @otherperson
Co-Authored-By: Claude Opus 4.6 <[email protected]>
EOF
)"
Push the new commit with a regular push:
git push
Read the current PR body:
gh pr view {pr_number} --json body --jq '.body'
For /save paths: In the removal manifest table, find the rows for saved paths and apply strikethrough with a [SAVED] tag. For example, change:
| plugin | `plugins/foo/` | No commits in 7 months, v0.0.1 |
To:
| ~~plugin~~ | ~~`plugins/foo/`~~ | ~~SAVED by @username~~ |
For /drop paths that undo a save: Remove the strikethrough and [SAVED] tag, restoring the row to its original state with the original reason (if available from git history of the PR body), or use a new reason:
| plugin | `plugins/foo/` | Dropped by @username |
For new /drop paths: Add a new row to the manifest table:
| command | `plugins/bar/commands/baz.md` | Manually dropped by @username |
Update the PR body:
gh pr edit {pr_number} --body "{updated_body}"
Add a summary comment:
gh pr comment {pr_number} --body "$(cat <<'EOF'
Processed `/save` and `/drop` comments.
**Saved** (restored and added to `.pruneprotect`):
- `plugins/foo/` — saved by @username
**Dropped** (removed):
- `plugins/bar/commands/baz.md` — dropped by @otherperson
Remaining removals: N items.
EOF
)"
Omit the Saved or Dropped section if there are no items for that category.
Print a summary to the user: what was restored, what was dropped, what remains in the PR, and the updated PR URL.
A summary of saved/dropped items and the updated PR state.
Process saves and drops on a specific PR:
/marketplace-ops:prune-update 42
Auto-detect the pruning PR:
/marketplace-ops:prune-update
On the pruning PR, trusted collaborators can comment:
/save plugins/foo/ # Restore and permanently protect
/drop plugins/bar/commands/baz.md # Undo a /save, or manually add a removal
/drop --force plugins/protected/ # Drop even if listed in .pruneprotect
9plugins reuse this command
First indexed Jul 11, 2026
Showing the 6 earliest of 9 plugins
npx claudepluginhub shivprakashmuley/ai-helpers --plugin marketplace-ops