From python-dev
Review the permission_guard.py hook log (path from $CLAUDE_HOOK_LOG) to find Bash commands that triggered permission prompts over a time window, then recommend updates to .claude/settings.json, .claude/settings.local.json, and .claude/scripts/permission_guard.py that would reduce future prompts. Triggers: "review permissions", "permission audit", "which commands keep prompting me", "/permission-review".
npx claudepluginhub vino9net/claude-python-skillThis skill is limited to using the following tools:
Analyze the permission_guard.py log to find which Bash commands
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
Analyze the permission_guard.py log to find which Bash commands triggered user prompts over a time window, then recommend changes that eliminate recurring prompts without loosening real guards.
/permission-review [days]
days — lookback window in days. Default: 2.CLAUDE_HOOK_LOG must be set for entries to exist. Resolve it
the same way permission_guard.py does:
~ → expand$CLAUDE_PROJECT_DIR, falling back to
$PWDIf the log file does not exist or has no permission_guard
entries in the window, stop and tell the user what to set (and
that logging only started from whenever the env var was first
defined).
Read the log as JSONL and keep entries where both:
hook == "permission_guard" (the log also contains
format_on_save entries — skip those)timestamp >= now - days (ISO 8601 UTC; use
datetime.fromisoformat)Bucket each kept entry by the decision string's prefix:
| Decision prefix | Meaning |
|---|---|
allow:* | Hook auto-granted. No prompt shown. |
deny:* | Hook blocked. No prompt shown. |
passthrough | User was prompted (unless a settings.json allow entry matched). This is the review target. |
passthrough:commit-on-<branch> | Intentional safety prompt for commits on protected branches. Do not recommend auto-allowing these. |
Report totals:
Window: last 2 days (2026-04-18 → 2026-04-20)
Entries: 342 permission_guard decisions
allow: 298
deny: 4
passthrough: 40 ← focus
For the passthrough bucket, group commands by a normalized prefix and show the top ~15:
{uv, git, gh, npm, npx, docker, kubectl, gcloud, aws, cargo, go}.Call out separately:
passthrough:commit-on-<branch> entries (safety-by-design — show
count, no recommendation).allow list would already match — those indicate a logging lag,
not a missing allow rule.Read $CLAUDE_PROJECT_DIR/.claude/settings.json and
.claude/settings.local.json (if present). Parse the
permissions.allow array from each.
For each top passthrough group:
Bash(<prefix>:*) entry covers the
command's prefix (best-effort prefix match; don't reimplement the
harness's full matcher — flag ambiguous cases).Split recommendations into two lists:
.claude/settings.json — team-safe patterns (e.g. gh pr:*,
make:*, docker build:*)..claude/settings.local.json — user/machine-specific patterns
(absolute paths, secrets-adjacent commands, anything with $HOME
or usernames).Present as a diff-style block; do NOT edit the files:
.claude/settings.json — proposed additions to permissions.allow:
+ "Bash(gh pr:*)" # 12 prompts
+ "Bash(make:*)" # 6 prompts
.claude/settings.local.json — proposed additions:
+ "Bash(/Users/.../mytool:*)" # 4 prompts
Read .claude/scripts/permission_guard.py and inspect
SAFE_COMMAND_PATTERNS. For each top passthrough group, decide:
terraform apply, kubectl delete, rm -rf). Instead,
suggest a narrower regex that excludes the dangerous subcommand,
or leave it as a prompt.kubectl delete on prod
contexts.Present the recommendation as a code block showing exactly which lines to add:
# Add to SAFE_COMMAND_PATTERNS in permission_guard.py:
r"^make\b",
r"^terraform (plan|validate|fmt|show|output)\b", # 'apply/destroy' excluded
One short paragraph:
request.cwd tells you which). If more than one project appears,
note it — the settings.json you're reading applies only to the
current project. Offer to filter by cwd == $CLAUDE_PROJECT_DIR
if the user wants project-scoped analysis.passthrough:commit-on-main / commit-on-master are intentional
— flag them so the user can see the count, but never recommend
auto-allowing commits on protected branches.