3 · Claude config — settings, modes, hooks
This step controls how much friction the agent operates with and installs the safety net that catches destructive commands regardless of mode. Two settings files, three permission presets, two hooks.
The committed-vs-personal split (again, because it matters)
Section titled “The committed-vs-personal split (again, because it matters)”| File | Committed? | Purpose |
|---|---|---|
.claude/settings.json | ✅ committed | Project-wide settings everyone shares — e.g. disabledMcpServers |
.claude/settings.local.json | ❌ gitignored | Personal permission mode — a per-developer friction choice |
.claude/.gitignore | ✅ committed | Ignores settings.local.json and *.bak.* |
1. .claude/settings.json (committed) — trim the MCP noise
Section titled “1. .claude/settings.json (committed) — trim the MCP noise”Only load MCPs this project actually uses. Disabling the rest speeds up sessions and reduces token overhead:
{ "disabledMcpServers": [ "Server Name Exactly As Shown In /mcp", "Another Unused Server" ]}Run /mcp in a session to get the exact display names, list the ones you don’t need here, commit the file. For a typical CodeCanyon Laravel project you keep a docs MCP (Context7), a browser MCP (Playwright), and — only if relevant — Stripe / DNS / hosting MCPs. Disable everything else.
2. .claude/.gitignore (committed)
Section titled “2. .claude/.gitignore (committed)”settings.local.json*.bak.*3. Permission modes — strict / medium / yolo
Section titled “3. Permission modes — strict / medium / yolo”settings.local.json carries your permission mode. The kit ships three presets and a set-claude-mode.sh switcher that installs one (with a timestamped backup and an allow-list merge so your accumulated approvals survive the switch).
| Mode | defaultMode | Posture | Use when |
|---|---|---|---|
| strict | plan | Read-only. No Bash/Edit/Write. Proposes diffs. | Security/deploy work, code review, unfamiliar code |
| medium | acceptEdits | Auto-allows edits + safe git/composer/npm/artisan. Asks for unknown Bash. | Default for active dev |
| yolo | bypassPermissions | Auto-allows almost everything — but a PreToolUse hook hard-blocks destructive commands. | Local throwaway / heavy refactors. Never on prod branches or with real creds. |
Apply one from the project root:
./.claude/claude-mode/bin/set-claude-mode.sh medium # strict | medium | yolo | showWhat medium looks like (excerpt)
Section titled “What medium looks like (excerpt)”{ "_mode": "medium", "defaultMode": "acceptEdits", "permissions": { "allow": ["Read","Grep","Glob","Edit","Write", "Bash(git status*)","Bash(git add *)","Bash(git commit *)", "Bash(composer install*)","Bash(npm run *)","Bash(php artisan *)", "Bash(vendor/bin/pest*)","Bash(vendor/bin/pint*)"], "deny": ["Bash(rm -rf /)","Bash(sudo *)","Bash(git push --force*)", "Bash(php artisan migrate:fresh*)","Bash(php artisan db:wipe*)", "Write(.env*)","Edit(.env*)"], "ask": ["Bash(rm *)","Bash(git push*)","Bash(ssh *)","Bash(mysql *)", "Bash(php artisan migrate:rollback*)","Bash(php artisan db:seed*)"] }}The full strict / medium / yolo presets ship in the kit’s claude-mode/templates/.
4. The hard-block hook — block-destructive.sh
Section titled “4. The hard-block hook — block-destructive.sh”The reason yolo is safe: a PreToolUse hook runs above the permission system and blocks destructive commands even under bypassPermissions. It’s wired into the yolo preset:
{ "defaultMode": "bypassPermissions", "hooks": { "PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": ".claude/claude-mode/hooks/block-destructive.sh" }] }] }}The hook reads the command from stdin and exits 2 (hard block) on patterns like rm -rf /, sudo, git push --force, chmod 777, curl | bash, migrate:fresh|wipe|reset, DROP TABLE, ::truncate(, and deletions of database/migrations or owned packages. Exit 2 is the highest-precedence signal — it can’t be overridden from inside a running session.
Precedence — which rule wins
Section titled “Precedence — which rule wins”- PreToolUse hook exit 2 → hard block (overrides everything, even bypass mode)
permissions.deny→ block- PreToolUse hook exit 1 → force prompt
permissions.ask→ promptpermissions.allow→ auto-approve- PreToolUse hook exit 0 → auto-approve
defaultModebehavior
Test the hook standalone (no agent needed):
echo '{"tool":"Bash","input":{"command":"rm -rf /"}}' | ./.claude/claude-mode/hooks/block-destructive.sh; echo "exit=$?" # → exit=2echo '{"tool":"Bash","input":{"command":"git status"}}' | ./.claude/claude-mode/hooks/block-destructive.sh; echo "exit=$?" # → exit=05. The vendor-edit guard hook (optional but recommended)
Section titled “5. The vendor-edit guard hook (optional but recommended)”CodeCanyon work lives or dies on not silently editing vendor code. A lightweight PostToolUse hook reminds you to wrap in-place vendor edits in ZAJ:BEGIN/END markers and log them in _CUSTOMIZATIONS.md whenever a file under vendor/, app/ core, or a vendor view is touched. The kit ships hooks/vendor-edit-reminder.sh and the wiring; it’s advisory (exit 0 with a stderr note), not a block.
✅ settings.json committed with a trimmed MCP list, .claude/.gitignore in place, a permission mode applied via the switcher and verified in a new session, the block-destructive hook tested. → Continue to Rules & skills.