104 lines
4.4 KiB
Markdown
104 lines
4.4 KiB
Markdown
|
|
---
|
||
|
|
name: hygiene
|
||
|
|
description: Manage stale and bloated docs. `/hygiene check` scans the project for stale/bloated documentation and writes a report; `/hygiene clean` applies documented findings; `/hygiene sweep` runs check then clean; `/hygiene status` shows the last check/clean/reminded timestamps and whether a report exists.
|
||
|
|
argument-hint: "[check [--scope <glob-or-path>] [--category <class|subtype>] | status | clean [--scope <glob-or-path>] [--category <class|subtype>] | sweep [--scope <glob-or-path>] [--category <class|subtype>]]"
|
||
|
|
---
|
||
|
|
|
||
|
|
# /hygiene — Documentation Hygiene
|
||
|
|
|
||
|
|
Single entry point for the doc-hygiene plugin. Dispatch on `$ARGUMENTS`.
|
||
|
|
|
||
|
|
Parse the first token of `$ARGUMENTS` as the subcommand; everything after it is
|
||
|
|
passed through. Scripts live under `${CLAUDE_PLUGIN_ROOT}/scripts/` (mirrors
|
||
|
|
`hooks/hooks.json`).
|
||
|
|
|
||
|
|
## `check [--scope <glob-or-path>] [--category <class|subtype>]`
|
||
|
|
|
||
|
|
Invoke the **`hygiene-check`** skill (Skill tool, `skill: "hygiene-check"`),
|
||
|
|
passing the `--scope` and `--category` arguments through verbatim. The skill owns
|
||
|
|
the full workflow — scan → classify → finalize → validate → write report → stamp
|
||
|
|
`last_check`. Do not scan or classify here; just route to the skill and surface
|
||
|
|
its summary.
|
||
|
|
|
||
|
|
## `status`
|
||
|
|
|
||
|
|
Read-only. No skill, no model, no scan. Run the state store directly and report
|
||
|
|
the three lifecycle timestamps plus whether a report exists. `state_store.py` is a
|
||
|
|
module (no CLI), so call it via `python3 -c`:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python3 -c '
|
||
|
|
import sys, os
|
||
|
|
sys.path.insert(0, os.environ["CLAUDE_PLUGIN_ROOT"] + "/scripts")
|
||
|
|
from state_store import StateStore, resolve_project_root
|
||
|
|
from pathlib import Path
|
||
|
|
s = StateStore(resolve_project_root(Path(os.getcwd())))
|
||
|
|
def fmt(dt): return dt.isoformat() if dt else "never"
|
||
|
|
print("last_check: " + fmt(s.get_last_check()))
|
||
|
|
print("last_clean: " + fmt(s.get_last_clean()))
|
||
|
|
print("last_reminded: " + fmt(s.get_last_reminded()))
|
||
|
|
print("report: " + ("present" if s.read_report() else "none"))
|
||
|
|
'
|
||
|
|
```
|
||
|
|
|
||
|
|
Present the output as a short human summary, for example:
|
||
|
|
|
||
|
|
```
|
||
|
|
doc-hygiene status for: <project-root>
|
||
|
|
|
||
|
|
last check 2026-06-20T14:03:11+00:00
|
||
|
|
last clean never
|
||
|
|
last reminded 2026-06-24T09:00:00+00:00
|
||
|
|
report present (run /hygiene check to refresh)
|
||
|
|
```
|
||
|
|
|
||
|
|
Do not classify or distill anything — these are timestamp reads only.
|
||
|
|
|
||
|
|
## `clean [--scope <glob-or-path>] [--category <class|subtype>]`
|
||
|
|
|
||
|
|
Invoke the **`hygiene-clean`** skill (Skill tool, `skill: "hygiene-clean"`),
|
||
|
|
passing the `--scope` and `--category` arguments through verbatim. The skill owns
|
||
|
|
the full workflow — load report → gate confirm-tier entries → apply deterministic
|
||
|
|
ops → dispatch generative ops → commit → stamp `last_clean`. Do not apply any
|
||
|
|
edits here; just route to the skill and surface its summary.
|
||
|
|
|
||
|
|
A report must exist before running `clean`. If the user has not yet run
|
||
|
|
`/hygiene check`, the skill will stop and instruct them to do so.
|
||
|
|
|
||
|
|
## `sweep [--scope <glob-or-path>] [--category <class|subtype>]`
|
||
|
|
|
||
|
|
`sweep` is check-then-clean: a convenience that runs both skills in sequence,
|
||
|
|
passing the same `--scope` and `--category` through to each.
|
||
|
|
|
||
|
|
1. **First**, invoke the **`hygiene-check`** skill (Skill tool,
|
||
|
|
`skill: "hygiene-check"`), passing `--scope` and `--category` verbatim.
|
||
|
|
Surface the check summary to the user.
|
||
|
|
|
||
|
|
2. **Then**, invoke the **`hygiene-clean`** skill (Skill tool,
|
||
|
|
`skill: "hygiene-clean"`), passing the same `--scope` and `--category`
|
||
|
|
verbatim.
|
||
|
|
|
||
|
|
The confirm gate in `hygiene-clean` applies identically under `sweep` — sweep
|
||
|
|
does **not** auto-approve any confirm-tier or generative entries. The user will
|
||
|
|
still be prompted to approve any entries that require it before any file
|
||
|
|
mutation occurs (invariant #7).
|
||
|
|
|
||
|
|
`sweep` produces at most one cleanup commit (the clean step); the check step
|
||
|
|
writes only to the gitignored `.dochygiene/` and does not commit.
|
||
|
|
|
||
|
|
## No arguments or unrecognized subcommand
|
||
|
|
|
||
|
|
Print usage, then run the `status` block above and show current state:
|
||
|
|
|
||
|
|
```
|
||
|
|
/hygiene — documentation hygiene
|
||
|
|
|
||
|
|
check [--scope <glob-or-path>] [--category <class|subtype>]
|
||
|
|
scan for stale/bloated docs and write a report
|
||
|
|
status show last check/clean/reminded timestamps + report presence
|
||
|
|
clean [--scope <glob-or-path>] [--category <class|subtype>]
|
||
|
|
apply documented findings (requires a report; run check first)
|
||
|
|
sweep [--scope <glob-or-path>] [--category <class|subtype>]
|
||
|
|
check then clean in sequence (confirm gate still applies)
|
||
|
|
```
|