Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/repo-hygiene/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "repo-hygiene",
"version": "0.10.57",
"version": "0.11.0",
"description": "Repo hygiene action-router: /repo-hygiene:clean sweeps reclaimable caches, build artifacts, and stale git metadata, and can realign the working tree to a fresh-pull state, dry-run-first, with destructive tiers gated behind explicit confirmation and a session-scoped destructive-command guard. Ecosystem targets are detected at runtime; secrets, runtime dependencies, and skill data are preserved by default.",
"author": {
"name": "Melodic Software",
Expand Down
52 changes: 50 additions & 2 deletions plugins/repo-hygiene/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,53 @@
All notable changes to the `repo-hygiene` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.11.0] - 2026-09-29

### Added

- **`clean-batch.sh --tier scan` inventories many repositories read-only (#3346).** It runs
`scan.sh` per selected repo with the shared repo selection and skip list, prints
`Outcome: scanned` per repo, and closes with `Summary: repos=N planned=0 bytes=K`. It writes
no plan; `--apply` and `--batch-plan` with it are usage errors. `resolve-clean-action.sh`
gains `scan-batch`, `scan-fleet`, and `inventory-batch`.
- **`git-branch-audit.sh` and `git-stash-audit.sh` audit many repositories (#3346).** Both take
`--repo`, `--repos-from`, `--skip`, and `--skip-from`, print a `Repo: <path>` block per repo,
audit linked worktrees that share a git common dir once, report a skipped or failing repo
without stopping the rest, and close with `FleetSummary:`. `--capture-file` with more than one
repo is a usage error. Deletion stays per repo.
- **The branch audit reports a WORKTREE branch's checkout path on a `Worktree:` line (#3346).**
The `git` action hands those branches to `/source-control:worktree cleanup --dry-run` and
re-audits; a clone blocked by being off the default branch is pointed at
`/repo-fleet-hygiene:sync`, shown as a command, not run.

### Changed

- **`git-branch-audit.sh` reads its facts in bulk (#3346).** One `for-each-ref`, two
`rev-list --stdin` passes, and one worktree read replace about six git processes per branch
(1404 to 110 git calls on a 242-branch fixture, stdout unchanged). A branch whose bulk record
cannot be trusted, or a pass that fails, takes the per-branch commands, so a verdict does not
depend on the path.

### Fixed

- **The clean skill's single-repo apply steps carry the `CLEAN_GUARD_ACK` prefix (#3346).**
`git-prune.sh`, `git-tree-reset.sh`, `remove-path.sh`, and the tree-batch step were shown
bare although the guard blocks `--apply` without it. `git-tree-reset.md` now says so, and the
duplicated argument list in `SKILL.md` points at the action router.

### Documentation

- **The guard's header, `SKILL.md`, and README state what the guard matches and leave the
branch-deletion question open (#3852).** They no longer call `git branch -D`/`-d` and
`git push --delete` a settled gap or make unsourced claims about them. Guard behavior and its
assertions are unchanged.
- **The clean skill documents the host permission layer that sits above the ack prefix (#3346).**
- **`setup check` and the README declare `node` (#3708).** Every hook row runs
`node hooks/exec-bash.mjs`, and Claude Code's native binary does not ship Node, so without it
the guard does not launch. `setup check` gains a `node` row probed through Bash, and its bash
lookup names the `PATH` step.
- **Reflowed the 0.10.55 bullet** on the `clean-batch.sh` preflight (whitespace only).

## [0.10.57] - 2026-09-28

### Fixed
Expand Down Expand Up @@ -32,8 +79,9 @@ All notable changes to the `repo-hygiene` plugin are documented here. Format fol
- **`clean-batch.sh` runs `preflight.sh` once before a caches/build/all dry-run
and prints `Progress:` on stderr (#3346).** `preflight.sh` takes optional
roots, and the batch passes its target repositories, so `RECENT_BUILD` covers
them wherever the batch runs from. The git-only tier does not run preflight. Apply does not run it again. Progress is `N/M <path>` on dry-run
and `apply N <path>` on apply.
them wherever the batch runs from. The git-only tier does not run preflight.
Apply does not run it again. Progress is `N/M <path>` on dry-run and
`apply N <path>` on apply.

## [0.10.54] - 2026-09-28

Expand Down
31 changes: 27 additions & 4 deletions plugins/repo-hygiene/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ guard.
`/repo-hygiene:clean <action>` routes every action below. Bare invocation infers
intent from the conversation, or presents a menu and falls back to the safe `scan`.
`/repo-hygiene:setup` is the separate, read-only prerequisite check. It verifies
`git`, the optional `ghq`, and the effective destructive-guard toggle, and cleans
`git`, `node`, the optional `ghq`, and the effective destructive-guard toggle, and cleans
nothing.

| Action | What it does | Risk |
Expand Down Expand Up @@ -44,6 +44,20 @@ ad-hoc loop. A skip entry that matches nothing is reported, never silently ignor
ghq list -p | /repo-hygiene:clean tree-batch --repos-from - --skip melodic-software/standards
```

### Multi-repo audits (read-only)

The branch and stash audits take the same repo selection as the batch tiers
(`--repo`, `--repos-from`, `--skip`, `--skip-from`) and print one `Repo: <path>`
block per repository. Linked worktrees of one repository are audited once, a
failing repo is reported without stopping the rest, and each repo writes its own
branch-tip capture (`--capture-file` is refused with more than one repo).
Deletion is not batched: run the delete from inside the audited repo, with that
repo's `TipCapture:` path.

```shell
ghq list -p | bash ${CLAUDE_PLUGIN_ROOT}/skills/clean/scripts/git-branch-audit.sh --repos-from -
```

## Safety model

- **Dry-run-first, always.** No tier applies on the first invocation; the agent
Expand All @@ -62,9 +76,9 @@ ghq list -p | /repo-hygiene:clean tree-batch --repos-from - --skip melodic-softw
`git checkout --`, recursive `Remove-Item`, the clean scripts when the command
contains `--apply`, and `git worktree remove` with a force flag. A dry-run is
not blocked. The confirmed command runs only through the skill's own gate.
It does not match `git branch -D` or
`git push --delete` (#3852); local branch deletion goes through
`git-branch-delete.sh` after the confirmation gate. Kill switch: the `clean_destructive_guard_enabled`
As of 2026-09-29 it does not match `git branch -D` or `git push --delete`;
whether it should is an open owner decision on #3852. The skill deletes local
branches with `git-branch-delete.sh` after the confirmation gate. Kill switch: the `clean_destructive_guard_enabled`
userConfig option set to `false` (`/plugin configure repo-hygiene@<marketplace>`, or
`claude plugin install repo-hygiene@<marketplace> --config clean_destructive_guard_enabled=false`),
both user-scoped. To disable per repository, disable the plugin in that project's
Expand All @@ -82,6 +96,15 @@ ghq list -p | /repo-hygiene:clean tree-batch --repos-from - --skip melodic-softw
- Conservative by default: the protected-path and preserve lists err toward
keeping a consumer's dependencies, credentials, and IDE state.

## Requirements

- `git` on PATH.
- Node.js on PATH. Every hook row runs `node hooks/exec-bash.mjs`, and Claude Code's native binary
neither ships nor uses Node, so without it the destructive guard does not launch and is not
enforced.
- `bash`: found on PATH, then `/bin/bash` and `/usr/bin/bash`; on Windows, Git Bash.
- `ghq` (optional) for the fleet batch actions' repository enumeration.

## Install

```shell
Expand Down
6 changes: 3 additions & 3 deletions plugins/repo-hygiene/scripts/allowed-tools-pairing.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ SKILLS=(clean)
# READ-ONLY scripts are pre-approved. The mutating ones (clean-caches,
# clean-build, git-prune, git-tree-reset[-batch], remove-path, clean-batch) must
# keep routing through the permission flow, which is the gate that actually
# covers them: the PreToolUse destructive guard matches destructive command
# SHAPES and matches none of these six scripts, so withholding the grant is the
# whole mechanism here, not a second line of defense.
# covers them: the PreToolUse destructive guard matches these scripts only in
# their --apply spelling, so the grant stays withheld and the guard is a
# second line, not the gate.
# Every one of them is bundled, executable, and invoked in the skill's
# markdown — so without this allowlist a grant added for any of them would
# satisfy every other check here and land silently.
Expand Down
Loading
Loading