跳到主要内容
知仓学习社ZHICANG

permission-check

Diagnose why Claude Code is (or isn't) prompting for permission. By default reads only repo-local layers (CLI project, CLI project-local, VSCode wor…

写文件严重 0 · 高危 2pedrohcgs/claude-code-my-workflow

它会碰到什么

扫了多少1 个文本文件,8 KB
它会碰到什么写文件
命中总数2 处
命中统计严重 0 · 高 2 · 中 0 · 低 0
逐条看命中(2 条严重或高危)
  • SKILL.md:21identity-config-write
    5. **CLI project-local settings** — `<repo>/.claude/settings.local.json`. Same key. Wins over project.
  • SKILL.md:44identity-config-write
    CLI_LOCAL="${CLAUDE_PROJECT_DIR}/.claude/settings.local.json"

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Permission Check

Purpose

Surface the full permission-mode picture across every layer Claude Code honors, so the user can see at a glance why prompts are (or aren't) firing. Claude Code resolves permission mode from a 6-tier stack; a single misconfigured layer produces silent overrides that are hard to debug by eye.

The 6 layers (precedence: bottom wins)

  1. VSCode user settings~/Library/Application Support/Code/User/settings.json (macOS), %APPDATA%/Code/User/settings.json (Windows), ~/.config/Code/User/settings.json (Linux). Key: claudeCode.initialPermissionMode.
  2. VSCode workspace settings<repo>/.vscode/settings.json. Same key. Wins over user.
  3. CLI user settings~/.claude/settings.json. Key: permissions.defaultMode.
  4. CLI project settings<repo>/.claude/settings.json. Same key. Wins over user.
  5. CLI project-local settings<repo>/.claude/settings.local.json. Same key. Wins over project.
  6. In-session mode — set at session start from layers 1-5, then mutable via Shift+Tab or /permission-mode. Authoritative until session ends.

Key insight: initialPermissionMode only fires at session start. If you toggled mid-session (or the session started before a settings change), the file-level settings are correct but the runtime mode differs. That's the #1 source of "bypass isn't working" confusion.

Privacy contract

Host-global settings files (~/.claude/settings.json, VSCode user settings) may contain:

  • Paths to unrelated projects and secrets
  • API keys, tokens, or provider credentials added outside this repo
  • Permission policies set by the user's org or employer

This skill is designed for defense-in-depth: Phase A runs automatically and reads only repo-local files. Phase B reads host-global files only after the user explicitly confirms — never silently. When reporting host-global layers, redact any key that is not directly relevant to permissions. or claudeCode..

Protocol

Phase A: Repo-local layers (auto-runs)

Read these immediately — they are checked into (or gitignored inside) the repo and do not cross the trust boundary:

VSCODE_WS="${CLAUDE_PROJECT_DIR}/.vscode/settings.json"
CLI_PROJECT="${CLAUDE_PROJECT_DIR}/.claude/settings.json"
CLI_LOCAL="${CLAUDE_PROJECT_DIR}/.claude/settings.local.json"

For each file that exists, extract:

  • VSCode workspace: claudeCode.initialPermissionMode, claudeCode.allowDangerouslySkipPermissions
  • CLI project / project-local: permissions.defaultMode, permissions.allow, permissions.deny

Missing files are fine — report "not present" rather than erroring.

Print the resolved defaultMode from these three layers alone. If that already explains the prompt behavior (e.g., CLI project-local has defaultMode: "default" while project has bypassPermissions), stop here and surface the diagnosis.

Phase B: Host-global layers (requires explicit user confirmation)

If Phase A is inconclusive — e.g., all repo-local layers agree on bypass but the user is still being prompted — ask the user:

> "To complete the diagnosis, I need to read two files outside this repo:

> - ~/.claude/settings.json (CLI user-level)

> - your VSCode user settings (~/Library/Application Support/Code/User/settings.json on macOS; Linux/Windows vary)

>

> These may contain unrelated paths or secrets. I will redact any key that isn't in permissions. or claudeCode.. Proceed?"

Only after the user confirms, read:

# VSCode user (platform-dependent path; try all three)
case "$(uname -s)" in
    Darwin)  VSCODE_USER="${HOME}/Library/Application Support/Code/User/settings.json" ;;
    Linux)   VSCODE_USER="${HOME}/.config/Code/User/settings.json" ;;
    MINGW*|MSYS*|CYGWIN*) VSCODE_USER="${APPDATA}/Code/User/settings.json" ;;
    *)       VSCODE_USER="" ;;
esac

CLI_USER="${HOME}/.claude/settings.json"

When reporting their contents, extract only the relevant keys:

  • CLI user: permissions.defaultMode, permissions.allow, permissions.deny
  • VSCode user: any key starting with claudeCode.

Never print the full file. Redact everything else to (other keys redacted).

Step 2: Compute resolved state

The resolved defaultMode is the value from the highest-precedence layer that sets it. Report:

  • Which layer won the defaultMode contest.
  • Merged allow list (union across CLI tiers).
  • Merged deny list (union; any deny blocks the action even if allowed elsewhere).
  • Whether VSCode says bypass but CLI says otherwise (or vice versa) — this is a legitimate conflict to flag.

Step 3: Report runtime mode

The live in-session mode is exposed via the status line (see .claude/scripts/statusline.sh). Tell the user:

> "Your status line shows the current in-session mode in the top-right of the Claude Code panel. If that disagrees with the resolved defaultMode above, you (or Shift+Tab) overrode it mid-session. Press Shift+Tab to cycle back."

If the status line isn't configured, emit a warning and point at .claude/scripts/statusline.sh.

Step 4: Flag common failure modes

Check for and explicitly call out:

  1. Layer drift: CLI project says bypass but CLI local says default → local wins, explains the prompts.
  2. VSCode-only bypass: VSCode layers say bypass but no CLI layer does → terminal Claude Code will still prompt; extension may or may not.
  3. Empty allowlist + default mode: defaultMode: "default" with empty allow → every tool prompts, as designed.
  4. Stale session: settings are correct but user reports prompts → almost always a session that pre-dates the fix. Advise "Cmd+Shift+P → Developer: Reload Window, then new Claude Code session."
  5. deny wins: any match in a deny list blocks the tool regardless of allow. Rare but deadly.

Output format

=== PERMISSION STATE ===

Layer 1 — VSCode user:       bypassPermissions      (allowDangerouslySkipPermissions: true)
Layer 2 — VSCode workspace:  bypassPermissions
Layer 3 — CLI user:          bypassPermissions      (allow: ["*"])
Layer 4 — CLI project:       bypassPermissions      (allow: ["Edit(**)", "Bash(*)", ...])
Layer 5 — CLI project-local: bypassPermissions      (allow: [...], deny: [])

Resolved defaultMode: bypassPermissions (set by Layer 5)
Merged allow:         Edit(**), Write(**), Bash(*), ...
Merged deny:          (none)

=== RUNTIME ===

Check the status line at the top of the Claude Code panel. Expected: [BYPASS].
If it shows [PROMPT], [AUTO-EDIT], or [PLAN] — that's an in-session override. Press Shift+Tab to cycle.

=== DIAGNOSIS ===

No layer drift detected. If you are still seeing prompts:
  1. Session is stale (started before settings were applied) — reload window + new session.
  2. VSCode extension bug — check extension version and file an issue.
  3. Tool was previously denied in this session — that denial is remembered. New session clears it.

If any layer disagrees, replace the "No layer drift detected" line with a specific flagged issue.

Notes

  • This skill is read-only. It never modifies settings.
  • If $CLAUDE_PROJECT_DIR is unset, fall back to git rev-parse --show-toplevel.
  • Platform-aware: detect macOS vs Linux vs Windows for the VSCode user path.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

它属于哪个仓库

星标★ 1,585
本站分层T1
该仓技能数60
原文件路径.claude/skills/permission-check/SKILL.md

同一个仓库里的其他技能

看这个仓库的全部 60 个技能