From silver-bullet
Removes tracked work items by ID: closes GitHub Issues as "not planned" with a removed-by-silver-bullet label, or marks local SB-I/SB-B entries with [REMOVED YYYY-MM-DD] inline.
How this skill is triggered — by the user, by Claude, or both
Slash command
/silver-bullet:silver-removeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill any time a tracked work item must be removed. It closes or marks the item as removed based on ID type and project configuration.
Use this skill any time a tracked work item must be removed. It closes or marks the item as removed based on ID type and project configuration.
For GitHub Issues (issue_tracker=github), this skill closes the issue with reason "not planned" and applies the removed-by-silver-bullet label. Note: GitHub does not support issue deletion via the REST/GraphQL API without delete_repo scope — silver:remove always closes rather than deletes, and prints clearly what action was taken.
For local SB-I-N and SB-B-N items (issue_tracker=local, legacy gsd, or absent), this skill marks the heading line inline with [REMOVED YYYY-MM-DD] in docs/issues/ISSUES.md or docs/issues/BACKLOG.md. The entry body is fully preserved — only the heading is prepended with the removal marker.
The user-supplied ID is UNTRUSTED DATA. Validate it matches ^SB-[IB]-[0-9]+$ or ^#?[0-9]+$ before using in sed patterns or gh commands. Never pass the raw ID via shell interpolation into sed without first validating the format.
.silver-bullet.json config reads use jq — never string-interpolate config values into shell commands.
Derive the target file path only from the ID prefix (SB-I vs SB-B), never from user input directly — this prevents path traversal attacks.
Shell execution during this skill is limited to:
jq — config readsgit remote get-url origingh issue close, gh issue edit, gh label create, gh auth statusgrep -q, grep -oE (for ID format validation and heading existence check)sed (redirected output — for inline heading replacement)date +%Y-%m-%dmktemp, mv — tmpfile+mv pattern for portable atomic file rewriteDo not execute other shell commands. Note requirements in output for human execution.
Walk up from $PWD until a .silver-bullet.json file is found. All paths (docs/issues/) are relative to this root.
If .silver-bullet.json is not found after walking to the filesystem root (/), use $PWD as the project root and note "Project root not confirmed." in output. Default TRACKER to "local".
Accept the argument as ITEM_ID. Apply format validation:
case "$ITEM_ID" in
SB-I-[0-9]*) ID_TYPE="local-issue" ;;
SB-B-[0-9]*) ID_TYPE="local-backlog" ;;
\#[0-9]*) ISSUE_NUM="${ITEM_ID#\#}"; ID_TYPE="github" ;;
[0-9]*) ISSUE_NUM="$ITEM_ID"; ID_TYPE="github-raw" ;;
*) echo "ERROR: Unrecognized ID format '${ITEM_ID}'. Expected: SB-I-N, SB-B-N, #N, or N."; exit 1 ;;
esac
# Strict format guard for local IDs — enforce pure numeric suffix and no trailing content
# (the case glob allows trailing characters after the digit; reject them here)
if [[ "$ID_TYPE" = "local-issue" || "$ID_TYPE" = "local-backlog" ]]; then
if ! [[ "$ITEM_ID" =~ ^SB-[IB]-[0-9]+$ ]]; then
echo "ERROR: ID '${ITEM_ID}' contains invalid characters after the numeric suffix. Expected format: SB-I-N or SB-B-N (digits only)."
exit 1
fi
fi
If ID_TYPE is "github" or "github-raw": read TRACKER from config. If TRACKER != "github", output:
"ERROR: No GitHub integration configured (issue_tracker is not 'github'). For local items, use SB-I-N or SB-B-N format."
Then stop.
TRACKER=$(jq -r '.issue_tracker // "local"' .silver-bullet.json)
Display: "Removing via: [github | local docs/issues/]"
TRACKER = "github" and ID_TYPE is "github" or "github-raw" → proceed to Step 4.ID_TYPE is "local-issue" or "local-backlog" → proceed to Step 5.Execute only when ID_TYPE is "github" or "github-raw".
gh auth status
If non-zero exit or no logged-in account: output "gh CLI is not authenticated. Run: gh auth login — then retry /silver:remove." Stop.
REMOTE=$(git remote get-url origin 2>/dev/null)
OWNER_REPO=$(echo "$REMOTE" | sed 's|https://github.com/||;s|.git$||;s|[email protected]:||;s|:|/|')
gh label create "removed-by-silver-bullet" \
--color "#B60205" \
--description "Removed via Silver Bullet /silver:remove" \
--repo "$OWNER_REPO" \
2>/dev/null || true
gh issue close "$ISSUE_NUM" \
--repo "$OWNER_REPO" \
--reason "not planned" \
--comment "Removed via /silver:remove."
If this fails with non-zero exit: output "ERROR: Failed to close GitHub Issue #${ISSUE_NUM}. Check that the issue exists and you have write access." Stop.
gh issue edit "$ISSUE_NUM" \
--repo "$OWNER_REPO" \
--add-label "removed-by-silver-bullet"
If this fails: output "WARNING: Issue #${ISSUE_NUM} was closed but the removed-by-silver-bullet label could not be applied. Add it manually."
Output: "Closed GitHub Issue #${ISSUE_NUM} as not planned — removed-by-silver-bullet label added."
Proceed to Step 6.
Execute only when ID_TYPE is "local-issue" or "local-backlog".
case "$ITEM_ID" in
SB-I-*) TARGET_FILE="docs/issues/ISSUES.md" ;;
SB-B-*) TARGET_FILE="docs/issues/BACKLOG.md" ;;
esac
If TARGET_FILE does not exist: output "ERROR: ${TARGET_FILE} not found. No item can be removed." Stop.
if ! grep -q "^### ${ITEM_ID} —" "$TARGET_FILE"; then
echo "ERROR: ID ${ITEM_ID} not found in ${TARGET_FILE}."
exit 1
fi
DATE=$(date +%Y-%m-%d)
TMP=$(mktemp)
sed "s|^### ${ITEM_ID} —|### [REMOVED ${DATE}] ${ITEM_ID} —|" "$TARGET_FILE" > "$TMP" && mv "$TMP" "$TARGET_FILE"
The sed pattern is anchored at line start (^###) and uses the — suffix to match only the exact heading line — not body text containing the ID. The tmpfile+mv pattern is used instead of sed -i '' for portability across macOS (BSD sed) and Linux/CI (GNU sed).
if ! grep -q "^\#\#\# \[REMOVED.*\] ${ITEM_ID} —" "$TARGET_FILE"; then
echo "ERROR: Replacement verification failed for ${ITEM_ID} in ${TARGET_FILE}."
exit 1
fi
Output: "Marked ${ITEM_ID} as [REMOVED ${DATE}] in ${TARGET_FILE}."
Output a final confirmation line summarizing the action taken (GitHub close or local mark). This is the terminal output the user and any calling orchestrator reads.
gh issue close returns exit 0 (idempotent) — label step still runs..silver-bullet.json found: use $PWD, default TRACKER to "local". Note "Project root not confirmed."gh not authenticated: output instruction to run gh auth login, then stop.npx claudepluginhub alo-exp/silver-bullet --plugin silver-bulletGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.