By komalboyo
Native macOS popup for Claude Code permission prompts — approve or deny from anywhere without switching back to the terminal.
Never miss a Claude Code permission prompt again.
You kick off a task in Claude Code, switch to your browser, and… nothing happens for ten minutes. You tab back and there it is — a permission prompt, patiently waiting, having blocked everything the whole time.
This tiny tool fixes that. When Claude Code needs permission, a native macOS dialog pops up front and center — over whatever app you're in — with a beep and one-tap buttons:
┌─────────────────────────────────────────────┐
│ ⚠️ Claude Code — my-app │
│ │
│ 📁 𝗺𝘆-𝗮𝗽𝗽 │
│ │
│ Tool: Bash │
│ │
│ git push origin main │
│ │
│ [ Deny ] [ Skip ] [ Approve ] │
└─────────────────────────────────────────────┘
The project folder you're approving for is always visible — in the dialog title and in bold at the top of the body — so you never approve the wrong session.
Hit Return to approve. That's it. Back to whatever you were doing.
osascript. No app, no daemon, no menu bar icon, no dependencies, nothing to keep running. A process spawns when a prompt appears and exits when you click.PermissionRequest event, which fires only when a permission dialog would appear. Auto-approved tools are untouched.Requirements: macOS, Claude Code ≥ 2.1.
Inside any Claude Code session:
/plugin marketplace add komalboyo/claude-popup-permissions
/plugin install popup-permissions@claude-popup-permissions
Clone this repo anywhere, then add to ~/.claude/settings.json:
{
"hooks": {
"PermissionRequest": [
{
"hooks": [
{
"type": "command",
"command": "osascript -l JavaScript \"/absolute/path/to/claude-popup-permissions/hooks/permission-popup.js\"",
"timeout": 150
}
]
}
]
}
}
New sessions pick it up automatically; already-running ones need /hooks opened once (or a restart).
First run: macOS may ask once to let your terminal display dialogs — click OK and you're set forever.
Claude Code's hooks system includes a PermissionRequest event that fires exactly when a permission prompt would appear, and whose stdout can answer it:
hooks/permission-popup.js, plain JXA) summarizes it into one readable line and shows a native displayDialog, activated to the front of all apps.| You press | Script prints | Result |
|---|---|---|
| Approve (or Return) | {"decision": {"behavior": "allow"}} | Tool runs instantly |
| Deny | {"decision": {"behavior": "deny"}} | Tool call blocked, Claude told why |
| Skip / Esc / timeout | nothing | Normal terminal prompt appears |
Environment variables (set them wherever you launch Claude Code):
| Variable | Default | What it does |
|---|---|---|
CLAUDE_POPUP_TIMEOUT | 120 | Seconds before the dialog gives up and falls back to the terminal |
CLAUDE_POPUP_TEST_BUTTON | – | Approve | Deny | Skip — bypasses the dialog, for testing wiring |
Try it without Claude Code:
echo '{"tool_name":"Bash","tool_input":{"command":"git push"},"cwd":"'$PWD'"}' \
| osascript -l JavaScript hooks/permission-popup.js
claude -p runs skip this hook by design.MIT — do whatever you like with it.
Matches all tools
Hooks run on every tool call, not just specific ones
Based on adoption, maintenance, documentation, and repository signals. Not a security audit or endorsement.
npx claudepluginhub komalboyo/claude-popup-permissions --plugin popup-permissionsSave and search tweets from Claude Code. Build a personal AI knowledge graph of curated X/Twitter posts with auto-categorization, tagging, and full-text search.
Ultra-compressed communication mode. Cuts 65% of output tokens (measured) while keeping full technical accuracy by speaking like a caveman.
Memory compression system for Claude Code - persist context across sessions
Multi-model consensus engine integrating OpenAI Codex CLI, Gemini CLI, and Claude CLI for collaborative code review and problem-solving.
45% cost reduction measured. Cache expiry prevention, SubTask auto-delegation, zero-cost context restoration, real-time cost dashboard. The only Claude Code plugin built from CC source analysis.