askill
plugin-settings

plugin-settingsSafety 95Repository

Configure per-project plugin settings using `.claude/plugin-name.local.md` files. Use when building plugins that need user-configurable behavior, storing agent state between sessions, or controlling hook activation per-project. Covers file structure, YAML frontmatter parsing, gitignore setup, and common patterns like toggle-based hooks and agent state management.

23 stars
1.2k downloads
Updated 4/4/2026

Package Files

Loading files...
SKILL.md

Plugin Settings Pattern

Per-project plugin configuration using .claude/plugin-name.local.md files with YAML frontmatter for structured settings and markdown body for additional context.

When to Use This Skill

Use plugin settings when...Use alternatives when...
Plugin needs per-project configurationSettings are global (use ~/.claude/settings.json)
Hooks need runtime enable/disable controlHook behavior is always-on
Agent state persists between sessionsState is ephemeral within a session
Users customize plugin behavior per-projectPlugin has no configurable behavior
Configuration includes prose/prompts alongside structured dataAll config is purely structured (use .json)

File Structure

Location

project-root/
└── .claude/
    └── plugin-name.local.md    # Per-project, user-local settings

Format

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

Naming Convention

  • Use .claude/plugin-name.local.md format
  • Match the plugin name exactly from plugin.json
  • The .local.md suffix signals user-local (not committed to git)

Gitignore

Add to project .gitignore:

.claude/*.local.md

Reading Settings

From Shell Scripts (Hooks)

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

Extract Markdown Body

# Get content after the closing --- frontmatter delimiter
BODY=$(awk '/^---$/{i++; next} i>=2' "$STATE_FILE")

From Skills and Agents

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

Common Patterns

Pattern 1: Toggle-Based Hook Activation

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

Pattern 2: Agent State Between Sessions

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.

Pattern 3: Configuration-Driven Validation

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

Implementation Checklist

When adding settings to a plugin:

  1. Design settings schema (fields, types, defaults)
  2. Create template in plugin README
  3. Add .claude/*.local.md to .gitignore
  4. Implement parsing using extract_field pattern
  5. Use quick-exit pattern ([[ -f "$STATE_FILE" ]] || exit 0)
  6. Provide sensible defaults when file is missing
  7. Document that changes require Claude Code restart (hooks only)

Best Practices

PracticeDetails
Quick exitCheck file existence first, exit 0 if absent
Sensible defaultsProvide fallback values when settings file is missing
Use extract_fieldStandard frontmatter extraction from shell-scripting.md
Validate valuesCheck numeric ranges, enum membership
File permissionsSettings files should be user-readable only (chmod 600)
Restart noticeDocument that hook-related changes need a Claude Code restart

Agentic Optimizations

ContextCommand
Check settings exist[[ -f ".claude/plugin.local.md" ]]
Extract single fieldhead -50 file | grep -m1 "^field:" | sed 's/^[^:]*:[[:space:]]*//'
Extract bodyawk '/^---$/{i++; next} i>=2' file
Quick enable check[[ "$(extract_field file enabled)" == "true" ]]

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

90/100Analyzed 3/28/2026

High-quality skill document about per-project plugin settings. Provides comprehensive coverage with clear when-to-use guidance, multiple implementation patterns, working bash code examples, and actionable checklist. Well-organized with tables and structured sections. Uses proper safety practices. Slight deduction for internal repo context, but content is genuinely reusable across plugin development.

95
90
90
90
85

Metadata

Licenseunknown
Version-
Updated4/4/2026
Publisherlaurigates

Tags

apillmpromptingsecurity