agent-patterns-plugin/skills/plugin-settings/SKILL.md
Configure per-project plugin settings via .claude/plugin-name.local.md files. Use when building plugins with user-configurable behavior, storing agent state, or controlling hooks.
npx skillsauth add laurigates/claude-plugins plugin-settingsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Per-project plugin configuration using .claude/plugin-name.local.md files with YAML frontmatter for structured settings and markdown body for additional context.
| Use plugin settings when... | Use alternatives when... |
|-----------------------------|--------------------------|
| Plugin needs per-project configuration | Settings are global (use ~/.claude/settings.json) |
| Hooks need runtime enable/disable control | Hook behavior is always-on |
| Agent state persists between sessions | State is ephemeral within a session |
| Users customize plugin behavior per-project | Plugin has no configurable behavior |
| Configuration includes prose/prompts alongside structured data | All config is purely structured (use .json) |
project-root/
└── .claude/
└── plugin-name.local.md # Per-project, user-local settings
---
enabled: true
mode: standard
max_retries: 3
allowed_extensions: [".js", ".ts", ".tsx"]
---
# Additional Context
Markdown body for prompts, instructions, or documentation
that hooks and agents can read and use.
.claude/plugin-name.local.md formatplugin.json.local.md suffix signals user-local (not committed to git)Add to project .gitignore:
.claude/*.local.md
Use the standard frontmatter extraction pattern from .claude/rules/shell-scripting.md:
#!/bin/bash
set -euo pipefail
STATE_FILE=".claude/my-plugin.local.md"
# Quick exit if not configured
[[ -f "$STATE_FILE" ]] || exit 0
# Extract field using standard pattern
extract_field() {
local file="$1" field="$2"
head -50 "$file" | grep -m1 "^${field}:" | sed 's/^[^:]*:[[:space:]]*//' | tr -d '\r'
}
plugin_enabled=$(extract_field "$STATE_FILE" "enabled")
[[ "$plugin_enabled" == "true" ]] || exit 0
plugin_mode=$(extract_field "$STATE_FILE" "mode")
# Get content after the closing --- frontmatter delimiter
BODY=$(awk '/^---$/{i++; next} i>=2' "$STATE_FILE")
Skills and agents read settings with the Read tool:
1. Check if `.claude/my-plugin.local.md` exists
2. Read the file and parse YAML frontmatter
3. Apply settings to current behavior
4. Use markdown body as additional context/prompt
Control hook activation without editing hooks.json:
#!/bin/bash
set -euo pipefail
STATE_FILE=".claude/security-scan.local.md"
[[ -f "$STATE_FILE" ]] || exit 0
extract_field() {
local file="$1" field="$2"
head -50 "$file" | grep -m1 "^${field}:" | sed 's/^[^:]*:[[:space:]]*//' | tr -d '\r'
}
scan_enabled=$(extract_field "$STATE_FILE" "enabled")
[[ "$scan_enabled" == "true" ]] || exit 0
# Hook logic runs only when enabled
Store agent task state for multi-session work:
---
agent_name: auth-implementation
task_number: 3.5
pr_number: 1234
enabled: true
---
# Current Task
Implement JWT authentication for the REST API.
Coordinate with auth-agent on shared types.
---
validation_level: strict
max_file_size: 1000000
allowed_extensions: [".js", ".ts", ".tsx"]
---
validation_level=$(extract_field "$STATE_FILE" "validation_level")
case "$validation_level" in
strict) run_strict_checks ;;
standard) run_standard_checks ;;
*) run_standard_checks ;; # Default
esac
When adding settings to a plugin:
.claude/*.local.md to .gitignoreextract_field pattern[[ -f "$STATE_FILE" ]] || exit 0)| Practice | Details |
|----------|---------|
| Quick exit | Check file existence first, exit 0 if absent |
| Sensible defaults | Provide fallback values when settings file is missing |
| Use extract_field | Standard frontmatter extraction from shell-scripting.md |
| Validate values | Check numeric ranges, enum membership |
| File permissions | Settings files should be user-readable only (chmod 600) |
| Restart notice | Document that hook-related changes need a Claude Code restart |
| Context | Command |
|---------|---------|
| Check settings exist | [[ -f ".claude/plugin.local.md" ]] |
| Extract single field | head -50 file \| grep -m1 "^field:" \| sed 's/^[^:]*:[[:space:]]*//' |
| Extract body | awk '/^---$/{i++; next} i>=2' file |
| Quick enable check | [[ "$(extract_field file enabled)" == "true" ]] |
testing
Verify accumulated bug claims at upstream HEAD and dedup against trackers before filing issues. Use when filing upstream reports from backlogs, audit docs, or git-history findings.
documentation
Gate outward-bound text (upstream issues, docs, PR bodies) through isolated haiku fresh-reader critique before publishing. Use when an artifact must survive a reader with zero project context.
tools
Suggest improvements to SKILL.md content, descriptions, or tool config from eval results. Use when raising pass rates, fixing triggering, or iterating on a skill after evaluation.
tools
deadbranch CLI for stale-branch cleanup — dry-run preview, TUI or non-interactive delete, protects main/develop/WIP. Use when asked to clean up branches, prune branches, or remove stale branches.