configuring-plugin-settings
Guides implementation of user-configurable plugin settings using the .claude/plugin-name.local.md pattern, including YAML frontmatter parsing, per-project configuration, settings file creation, and reading settings from hooks, commands, and agents. Activates when the user asks about plugin settings, .local.md files, plugin state files, per-project configuration, or wants to make plugin behavior configurable.
What this skill does
# Plugin Settings Pattern for Claude Code Plugins
## Overview
Plugins can store user-configurable settings and state in `.claude/plugin-name.local.md` files within the project directory. This pattern uses YAML frontmatter for structured configuration and markdown content for prompts or additional context.
**Key characteristics:**
- File location: `.claude/plugin-name.local.md` in project root
- Structure: YAML frontmatter + markdown body
- Purpose: Per-project plugin configuration and state
- Usage: Read from hooks, commands, and agents
- Lifecycle: User-managed (not in git, should be in `.gitignore`)
## File Structure
### Basic Template
```markdown
---
enabled: true
setting1: value1
setting2: value2
numeric_setting: 42
list_setting: ["item1", "item2"]
---
# Additional Context
This markdown body can contain:
- Task descriptions
- Additional instructions
- Prompts to feed back to Claude
- Documentation or notes
```
### Example: Plugin State File
**.claude/my-plugin.local.md:**
```markdown
---
enabled: true
strict_mode: false
max_retries: 3
notification_level: info
coordinator_session: team-leader
---
# Plugin Configuration
This plugin is configured for standard validation mode.
Contact @team-lead with questions.
```
## Reading Settings Files
### From Hooks (Bash Scripts)
**Pattern: Check existence and parse frontmatter**
```bash
#!/bin/bash
set -euo pipefail
# Define state file path
STATE_FILE=".claude/my-plugin.local.md"
# Quick exit if file doesn't exist
if [[ ! -f "$STATE_FILE" ]]; then
exit 0 # Plugin not configured, skip
fi
# Parse YAML frontmatter (between --- markers)
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$STATE_FILE")
# Extract individual fields
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//' | sed 's/^"\(.*\)"$/\1/')
STRICT_MODE=$(echo "$FRONTMATTER" | grep '^strict_mode:' | sed 's/strict_mode: *//' | sed 's/^"\(.*\)"$/\1/')
# Check if enabled
if [[ "$ENABLED" != "true" ]]; then
exit 0 # Disabled
fi
# Use configuration in hook logic
if [[ "$STRICT_MODE" == "true" ]]; then
# Apply strict validation
# ...
fi
```
See `examples/read-settings-hook.sh` for complete working example.
### From Commands
Commands can read settings files to customize behavior:
```markdown
---
description: Process data with plugin
allowed-tools: ["Read", "Bash"]
---
# Process Command
Steps:
1. Check if settings exist at `.claude/my-plugin.local.md`
2. Read configuration using Read tool
3. Parse YAML frontmatter to extract settings
4. Apply settings to processing logic
5. Execute with configured behavior
```
### From Agents
Agents can reference settings in their instructions:
```markdown
---
name: configured-agent
description: Agent that adapts to project settings
---
Check for plugin settings at `.claude/my-plugin.local.md`.
If present, parse YAML frontmatter and adapt behavior according to:
- enabled: Whether plugin is active
- mode: Processing mode (strict, standard, lenient)
- Additional configuration fields
```
## Parsing Techniques
### Extract Frontmatter
```bash
# Extract everything between --- markers
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$FILE")
```
### Read Individual Fields
**String fields:**
```bash
VALUE=$(echo "$FRONTMATTER" | grep '^field_name:' | sed 's/field_name: *//' | sed 's/^"\(.*\)"$/\1/')
```
**Boolean fields:**
```bash
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')
# Compare: if [[ "$ENABLED" == "true" ]]; then
```
**Numeric fields:**
```bash
MAX=$(echo "$FRONTMATTER" | grep '^max_value:' | sed 's/max_value: *//')
# Use: if [[ $MAX -gt 100 ]]; then
```
### Read Markdown Body
Extract content after second `---`:
```bash
# Get everything after closing ---
BODY=$(awk '/^---$/{i++; next} i>=2' "$FILE")
```
## Common Patterns
### Pattern 1: Temporarily Active Hooks
Use settings file to control hook activation:
```bash
#!/bin/bash
STATE_FILE=".claude/security-scan.local.md"
# Quick exit if not configured
if [[ ! -f "$STATE_FILE" ]]; then
exit 0
fi
# Read enabled flag
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$STATE_FILE")
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')
if [[ "$ENABLED" != "true" ]]; then
exit 0 # Disabled
fi
# Run hook logic
# ...
```
**Use case:** Enable/disable hooks without editing hooks.json (requires restart).
### Pattern 2: Agent State Management
Store agent-specific state and configuration:
**.claude/multi-agent-swarm.local.md:**
```markdown
---
agent_name: auth-agent
task_number: 3.5
pr_number: 1234
coordinator_session: team-leader
enabled: true
dependencies: ["Task 3.4"]
---
# Task Assignment
Implement JWT authentication for the API.
**Success Criteria:**
- Authentication endpoints created
- Tests passing
- PR created and CI green
```
Read from hooks to coordinate agents:
```bash
AGENT_NAME=$(echo "$FRONTMATTER" | grep '^agent_name:' | sed 's/agent_name: *//')
COORDINATOR=$(echo "$FRONTMATTER" | grep '^coordinator_session:' | sed 's/coordinator_session: *//')
# Send notification to coordinator
tmux send-keys -t "$COORDINATOR" "Agent $AGENT_NAME completed task" Enter
```
### Pattern 3: Configuration-Driven Behavior
**.claude/my-plugin.local.md:**
```markdown
---
validation_level: strict
max_file_size: 1000000
allowed_extensions: [".js", ".ts", ".tsx"]
enable_logging: true
---
# Validation Configuration
Strict mode enabled for this project.
All writes validated against security policies.
```
Use in hooks or commands:
```bash
LEVEL=$(echo "$FRONTMATTER" | grep '^validation_level:' | sed 's/validation_level: *//')
case "$LEVEL" in
strict)
# Apply strict validation
;;
standard)
# Apply standard validation
;;
lenient)
# Apply lenient validation
;;
esac
```
## Creating Settings Files
### From Commands
Commands can create settings files:
```markdown
# Setup Command
Steps:
1. Ask user for configuration preferences
2. Create `.claude/my-plugin.local.md` with YAML frontmatter
3. Set appropriate values based on user input
4. Inform user that settings are saved
5. Remind user to restart Claude Code for hooks to recognize changes
```
### Template Generation
Provide template in plugin README:
```markdown
## Configuration
Create `.claude/my-plugin.local.md` in your project:
\`\`\`markdown
---
enabled: true
mode: standard
max_retries: 3
---
# Plugin Configuration
Your settings are active.
\`\`\`
After creating or editing, restart Claude Code for changes to take effect.
```
## Best Practices
### File Naming
✅ **DO:**
- Use `.claude/plugin-name.local.md` format
- Match plugin name exactly
- Use `.local.md` suffix for user-local files
❌ **DON'T:**
- Use different directory (not `.claude/`)
- Use inconsistent naming
- Use `.md` without `.local` (might be committed)
### Gitignore
Always add to `.gitignore`:
```gitignore
.claude/*.local.md
.claude/*.local.json
```
Document this in plugin README.
### Defaults
Provide sensible defaults when settings file doesn't exist:
```bash
if [[ ! -f "$STATE_FILE" ]]; then
# Use defaults
ENABLED=true
MODE=standard
else
# Read from file
# ...
fi
```
### Validation
Validate settings values:
```bash
MAX=$(echo "$FRONTMATTER" | grep '^max_value:' | sed 's/max_value: *//')
# Validate numeric range
if ! [[ "$MAX" =~ ^[0-9]+$ ]] || [[ $MAX -lt 1 ]] || [[ $MAX -gt 100 ]]; then
echo "⚠️ Invalid max_value in settings (must be 1-100)" >&2
MAX=10 # Use default
fi
```
### Restart Requirement
**Important:** Settings changes require Claude Code restart.
Document in your README:
```markdown
## Changing Settings
After editing `.claude/my-plugin.local.md`:
1. Save the file
2. Exit Claude Code
3. Restart: `claude` or `cc`
4. New settings will be loaded
```
Hooks cannot be hot-swapped within a session.
## Security Considerations
### Sanitize User Input
When writing settings files from user input:
```bash
# Escape quotes in user input
SAFE_VALUE=$(ecRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.