一键导入
permissions-review
Review and update Claude Code's auto-approved command allowlist based on Bash commands that triggered permission prompts in recent sessions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Review and update Claude Code's auto-approved command allowlist based on Bash commands that triggered permission prompts in recent sessions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | permissions-review |
| description | Review and update Claude Code's auto-approved command allowlist based on Bash commands that triggered permission prompts in recent sessions. |
| disable-model-invocation | true |
Scan recent sessions for Bash commands that triggered permission prompts, then recommend and apply allowlist additions. Reduce friction for read-only / benign operations; keep state-modifying commands gated. The review is complete when every signature the scanner reports has landed in exactly one bucket: allowlisted, rejected, or raised with the user.
git add/commit/push/reset/checkout/stash, docker exec/stop/rm/run/build, rm/mv/cp/mkdir/chmod, sed -i, file writes, database mutations, npm install, uv add/sync, pip install. Anything that modifies state, even benignly.python, node, bash, eval), package runners, task-runner wildcards (make *, npm run *, cargo run *), gh api * without -X GET. An exact invocation is fine (Bash(make check)); the wildcard is not. Standing exceptions in the global allowlist (uv run *, uvx *, the ssh * <read-cmd> patterns backed by the ssh-docker-guard hook) are deliberate — keep them, don't widen them, don't add new ones without the user.duckdb / sqlite3 — can write, but often used for analytics reads only. Project-local if allowed.bash <script> — depends entirely on script content. Usually skip.make targets — safe if read-only, but varies. Always project-local, always exact.Global settings (always applies): ~/.claude/settings.json. If this is a symlink (dotfiles), note the canonical path for editing.
Project-level settings (current project only): <project-root>/.claude/settings.json.
Read both to understand what's already allowed.
uv run <skill-dir>/scripts/scan_unapproved.py \
<sessions_dir> \
<global_settings_path> [<project_settings_path>] \
--days <N>
<sessions_dir>: ~/.claude/projects/<project-path-encoded>/ (path encoding: replace / with -, strip leading slash)--days N: how far back to scan (default 30, user may request 60+)--help for full usageThe script reads the actual allowlist from the settings files, so it stays in sync. Output is JSON: [{signature, count, example}, ...] sorted by frequency.
The scanner flags anything not matching the allowlist files — but Claude Code auto-allows many read-only commands internally, and those never prompt, so an entry for them is dead weight. Drop them first:
cat, head, tail, wc, stat, ls, echo, date, diff, df, du, id, uname, free, uptime, basename, dirname, realpath, readlink, cut, tr, which, type, seq, sleep, nproc, strings.grep/rg, fd, jq, sort, uniq, find (blocks -delete/-exec), sed (read-only expressions), ps, lsof, pgrep, ss, tree, man, file, hostname, sha256sum, md5sum, xargs, base64.pwd, whoami.git status/log/diff/show/blame/branch/tag/remote/ls-files/rev-parse/describe/reflog/..., gh pr view/list/diff/checks, gh issue view/list, gh run list/view, gh api (GET), gh auth status, ...docker ps/images/logs/inspect.The set is version-dependent — when unsure whether a command still prompts, test it rather than guessing.
Of what remains, drop one-offs (fewer than ~3 occurrences) unless clearly recurring across projects, and cap recommendations at ~20 so the user can skim. Then place every remaining signature in one bucket of the safety bar and present a table: signature, count, bucket, one-line rationale.
Split additions:
~/.dotfiles/claude/settings.json or wherever the canonical source is): universal read-only commands useful across all projects.<project>/.claude/settings.json): project-specific make targets, domain tools.Insert new entries in the appropriate section of the JSON, maintaining the existing grouping style (basic commands, search tools, nix, system, dev tooling, git, gh, ssh, docker). Preserve existing entries; de-duplicate; don't touch permissions.deny or other settings fields.
Format: "Bash(<command_pattern> *)" — the * at end matches any trailing arguments.
Gotcha — trailing * requires at least one argument. "Bash(git status *)" matches git status -s but NOT bare git status. For commands commonly called without arguments, add BOTH the bare and * variants:
"Bash(git status)",
"Bash(git status *)",
For SSH remote commands: "Bash(ssh * <command> *)" — the first * matches the hostname. Same trailing-* caveat applies: "Bash(ssh * nvidia-smi)" is needed alongside the * variant for bare invocations.
Gotcha — SSH glob patterns are inherently over-broad. ssh * docker ps * matches ANY SSH command containing "docker ps" anywhere in the string, including ssh host docker exec $(docker ps -q) evil-cmd. The * wildcards match across the full command, not just individual arguments. This means "read-only" SSH docker patterns can be exploited to run docker exec/run/stop/rm over SSH without approval.
Mitigation: the mx plugin includes a PreToolUse hook (hooks/ssh-docker-guard.sh) that acts as a deny-list — it blocks SSH commands containing dangerous docker subcommands (exec, run, stop, rm, kill, build, push, pull, restart, update, create) regardless of what the glob allowlist permits. If reviewing SSH docker patterns, verify this hook is active rather than trying to fix it at the glob level.
Commit each settings file to its respective repo with a descriptive message.
Work a feature's ticket DAG in parallel — one orchestrator fans independent frontier tickets out to parallel worker agents and integrates them on the feature branch until the feature ships. Use when a ticketed feature has independent frontier tickets, the user says "dispatch" or wants tickets worked in parallel, or when another skill routes parallel frontier work here.
Which mx skill or flow fits the current situation — a router over the mx workflow.
Run commands in tmux whenever they run long or need eyes on them — anything expected to take more than ~30–60s (training runs, ML experiments, builds, servers), anything worth observing mid-run (progress logs, monitoring output), and anything interactive (sudo prompts, REPLs, wizards), locally or on a remote host. Always reach for this instead of a fire-and-forget Bash call in those cases — the human can attach and step in at any time.
Break a plan, spec, or the current conversation into a set of tracer-bullet tickets, each declaring its blocking edges, published per the tracker conventions — ticket files with blocked-by edges, or native blocking links on a real tracker.
Turn the current conversation into a spec and publish it to the project issue tracker — no interview, just synthesis of what you've already discussed.
File-based issue tracker conventions — how specs, tickets, and small tasks live in agent/tasks/ and how to publish, fetch, claim, and retire them. Use when publishing or fetching a spec/ticket/task, picking work from the frontier, or when another skill says "publish to the issue tracker".