Skip to content

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)”
FileCommitted?Purpose
.claude/settings.json✅ committedProject-wide settings everyone shares — e.g. disabledMcpServers
.claude/settings.local.json❌ gitignoredPersonal permission mode — a per-developer friction choice
.claude/.gitignore✅ committedIgnores 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.

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).

ModedefaultModePostureUse when
strictplanRead-only. No Bash/Edit/Write. Proposes diffs.Security/deploy work, code review, unfamiliar code
mediumacceptEditsAuto-allows edits + safe git/composer/npm/artisan. Asks for unknown Bash.Default for active dev
yolobypassPermissionsAuto-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:

Terminal window
./.claude/claude-mode/bin/set-claude-mode.sh medium # strict | medium | yolo | show
{
"_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.

  1. PreToolUse hook exit 2 → hard block (overrides everything, even bypass mode)
  2. permissions.deny → block
  3. PreToolUse hook exit 1 → force prompt
  4. permissions.ask → prompt
  5. permissions.allow → auto-approve
  6. PreToolUse hook exit 0 → auto-approve
  7. defaultMode behavior

Test the hook standalone (no agent needed):

Terminal window
echo '{"tool":"Bash","input":{"command":"rm -rf /"}}' | ./.claude/claude-mode/hooks/block-destructive.sh; echo "exit=$?" # → exit=2
echo '{"tool":"Bash","input":{"command":"git status"}}' | ./.claude/claude-mode/hooks/block-destructive.sh; echo "exit=$?" # → exit=0
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.