Diagnose why Claude Code is (or isn't) prompting for permission. By default reads only repo-local layers (CLI project, CLI project-local, VSCode workspace). Host-global layers (CLI user `~/.claude/`, VSCode user settings) are read ONLY when the user explicitly confirms — those files may contain unrelated paths or secrets. Use when user says "why is it asking me to approve?", "permission check", "why am I getting prompts?", "bypass isn't working", "check my permissions". Read-only diagnostic.
npx skills add https://github.com/pedrohcgs/claude-code-my-workflow --skill permission-check
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.
~/Library/Application Support/Code/User/settings.json (macOS), %APPDATA%/Code/User/settings.json (Windows), ~/.config/Code/User/settings.json (Linux). Key: claudeCode.initialPermissionMode.<repo>/.vscode/settings.json. Same key. Wins over user.~/.claude/settings.json. Key: permissions.defaultMode.<repo>/.claude/settings.json. Same key. Wins over user.<repo>/.claude/settings.local.json. Same key. Wins over project.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.
Host-global settings files (~/.claude/settings.json, VSCode user settings) may contain:
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.*.
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:
claudeCode.initialPermissionMode, claudeCode.allowDangerouslySkipPermissionspermissions.defaultMode, permissions.allow, permissions.denyMissing 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.
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:
permissions.defaultMode, permissions.allow, permissions.denyclaudeCode.Never print the full file. Redact everything else to (other keys redacted).
The resolved defaultMode is the value from the highest-precedence layer that sets it. Report:
defaultMode contest.allow list (union across CLI tiers).deny list (union; any deny blocks the action even if allowed elsewhere).bypass but CLI says otherwise (or vice versa) — this is a legitimate conflict to flag.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.
Check for and explicitly call out:
defaultMode: "default" with empty allow → every tool prompts, as designed.deny wins: any match in a deny list blocks the tool regardless of allow. Rare but deadly.=== 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.
$CLAUDE_PROJECT_DIR is unset, fall back to git rev-parse --show-toplevel.This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.
Build agentic applications with GitHub Copilot SDK. Use when embedding AI agents in apps, creating custom tools, implementing streaming responses, managing sessions, connecting to MCP servers, or creating custom agents. Triggers on Copilot SDK, GitHub SDK, agentic app, embed Copilot, programmable agent, MCP server, custom agent.
Coding Agent Session Search - unified CLI/TUI to index and search local coding agent history from Claude Code, Codex, Gemini, Cursor, Aider, ChatGPT, Pi-Agent, Factory, and more. Purpose-built for AI agent consumption with robot mode.
Destructive Command Guard - High-performance Rust hook for Claude Code that blocks dangerous commands before execution. SIMD-accelerated, modular pack system, whitelist-first architecture. Essential safety layer for agent workflows.
Makepad UI development skills for Rust apps: setup, patterns, shaders, packaging, and troubleshooting.
Secure environment variable management ensuring secrets are never exposed in Claude sessions, terminals, logs, or git commits
Prompt for generating an AGENTS.md file for a repository
Take pedrohcgs/permission-check from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.