burp-search
CommandSearches Burp Suite project files for security analysis
Safely analyzes and cleans up local git branches and worktrees, categorizing them as merged, squash-merged, superseded, or active work before deleting anything.
> /plugin marketplace add trailofbits/skills
description: "Safely analyzes and cleans up local git branches and worktrees, categorizing them as merged, squash-merged, superseded, or active work before deleting anything." argument-hint: "[repo-path]" disable-model-invocation: true allowed-tools: Bash Read AskUserQuestion Workflow
Clean up accumulated git worktrees and local branches. A dynamic workflow gathers the evidence in parallel and tries to disprove its own delete recommendations; you keep the two safety gates and run the deletions yourself.
Repository: `$ARGUMENTS` — when empty, use the current working directory.
**Never delete anything without explicit user confirmation.**
The split between the workflow and this session is the safety property, not an implementation detail:
| Runs in the workflow (subagents) | Runs here (main session) | |----------------------------------|--------------------------| | Read-only inspection of git state | Both user gates | | Merge-evidence investigation | Every `git branch -d/-D` | | Refutation of delete candidates | Every `git worktree remove` |
Workflow agents run in the background with no way to reach the user. Nothing destructive may move into the script — if it did, deletions would happen while the user was still being asked about them.
`${CLAUDE_PLUGIN_ROOT}` is set in the Bash tool's environment, not in this prompt's text — nothing expands it for you here. **Resolve it first**, in the same call that finds the repo root:
echo "$CLAUDE_PLUGIN_ROOT" git rev-parse --show-toplevel
Then call the `Workflow` tool with `scriptPath` set to `<that plugin root>/workflows/analyze-branches.js` and this as `args`, both values substituted rather than passed as the literal `${CLAUDE_PLUGIN_ROOT}`:
{ "repoPath": "<absolute path to the repo>", "pluginDir": "<that plugin root>" }This command being invoked is the opt-in that workflow needs.
It runs three phases — survey, investigate, refute — and returns:
| Field | Meaning | |-------|---------| | `deleteCandidates` | Recommended deletions. Each carries `evidence`, the exact `command` (`-d` or `-D`), `worktreePath` when a worktree holds the branch, `group` for related-branch display, and `verifyWith` on `SAFE_TO_DELETE` entries. | | `needsReview` | Remote gone, work not found in the default branch. Never recommend these. | | `keep` | Unpushed, local-only, or synced with a live remote — plus `PROTECTED` entries, excluded from analysis but still reported. | | `worktrees` | Path, branch, `dirty`, `dirtyFiles`, and whether the branch is stale. | | `unanalyzed` | Branches no verdict came back for. **Must be shown to the user.** |
**Exit criteria:** you hold a result object, or the workflow threw.
If it throws with "survey returned zero local branches", the inventory failed — say so and stop. Do not report a clean repository.
If it throws about an unreadable `scriptPath`, the path did not resolve — most likely `$CLAUDE_PLUGIN_ROOT` was empty or reached the tool unexpanded. Check what the `echo` above printed, and if there is no usable plugin root, take the inline fallback below rather than aborting the run.
**Fallback.** If the `Workflow` tool is unavailable, do the same analysis inline: read [merge-evidence.md](../references/merge-evidence.md), gather the state below, and apply the decision table in [Phase 2](#phase-2-check-the-workflows-work). It is slower and the refutation pass is on you, but the categories and the gates are identical.
# Assign, then default with ${:-}. Do not fall back with `... | sed ... || echo main`:
# a pipeline's status is the last command's, sed succeeds on empty input, so the ||
# never fires and default_branch ends up empty — every command below then silently
# operates on "".
default_branch=$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null)
default_branch="${default_branch#origin/}"
default_branch="${default_branch:-main}"
git fetch --prune
git branch -vv # tracking info and [gone] markers
git branch --merged "$default_branch"
git worktree list --porcelain
git log --oneline "$default_branch" | grep -iE "#[0-9]+" | head -40The workflow reports evidence so you can audit it, not so you can forward it unread. Before building the gate-1 table:
1. **Every `deleteCandidate` names specific evidence** — a PR number, a commit sha, or a superseding branch. "Similar name", "looks stale", or an empty evidence string is not a delete recommendation. Move it to needs-review. `SAFE_TO_DELETE` entries satisfy this by naming the tip commit; they also carry `verifyWith`, which phase 3 runs before deleting. 2. **No protected branch is a delete candidate.** The script filters long-lived integration and environment names (`main`, `master`, `develop`, `dev`, `staging`, `production`, `qa`, `uat`, `release/*`, `hotfix/*`, and similar), plus the repository's actual default branch and the current branch, programmatically. They do still appear — under `keep` with category `PROTECTED`, and with their unpushed count when they have one. That is deliberate: excluded from analysis is not the same as absent from the report, and a `staging` branch carrying unpushed commits must not vanish. If one reaches `deleteCandidates` or `needsReview` regardless, drop it and say so. 3. **`unanalyzed` is empty, or you list it.** A partial run must not read as a complete one. 4. **Dirty worktrees are flagged**, whatever their branch's category.
The categories, and what has to be true for each:
| Category | Meaning | Delete Command | |----------|---------|----------------| | SAFE_TO_DELETE | Reported by `git branch --merged`, re-checked by `verifyWith` at execution | `git branch -d` | | SQUASH_MERGED | Work incorporated via squash merge, PR or commit named | `git branch -D` | | SUPERSEDED | Work verified in main via PR, or contained in a named newer branch
Trail of Bits skills and plugins for AI-assisted security analysis, testing, and development. Install this marketplace in Claude Code or Codex, or import it into your ChatGPT workspace marketplace.
Searches Burp Suite project files for security analysis
Performs security-focused differential review of code changes
Identifies state-changing entry points in smart contracts
Scans Android APKs for Firebase security misconfigurations
Audit a file, directory, or whole repo for insecure default configuration: fallback secrets, default credentials, fail-open…
Check text against AGT prompt-injection, context-poisoning, and MCP threat detectors.
Show which external bug-bounty tools are installed on this machine and print install hints for the missing ones. Curated from…
Show which external bug-bounty tools are installed on this machine and print install hints for the missing ones. Curated from…