All skills
Skillintermediate

Real-World Plugin Settings Examples

Detailed analysis of how production plugins use the `.claude/plugin-name.local.md` pattern.

Claude Code Knowledge Pack7/10/2026

Overview

Real-World Plugin Settings Examples

Detailed analysis of how production plugins use the .claude/plugin-name.local.md pattern.

multi-agent-swarm Plugin

Settings File Structure

.claude/multi-agent-swarm.local.md:

---
agent_name: auth-implementation
task_number: 3.5
pr_number: 1234
coordinator_session: team-leader
enabled: true
dependencies: ["Task 3.4"]
additional_instructions: "Use JWT tokens, not sessions"
---

# Task: Implement Authentication

Build JWT-based authentication for the REST API.

## Requirements
- JWT token generation and validation
- Refresh token flow
- Secure password hashing

## Success Criteria
- Auth endpoints implemented
- Tests passing (100% coverage)
- PR created and CI green
- Documentation updated

## Coordination
Depends on Task 3.4 (user model).
Report status to 'team-leader' session.

How It's Used

File: hooks/agent-stop-notification.sh

Purpose: Send notifications to coordinator when agent becomes idle

Implementation:

#!/bin/bash
set -euo pipefail

SWARM_STATE_FILE=".claude/multi-agent-swarm.local.md"

# Quick exit if no swarm active
if [[ ! -f "$SWARM_STATE_FILE" ]]; then
  exit 0
fi

# Parse frontmatter
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$SWARM_STATE_FILE")

# Extract configuration
COORDINATOR_SESSION=$(echo "$FRONTMATTER" | grep '^coordinator_session:' | sed 's/coordinator_session: *//' | sed 's/^"\\(.*\\)"$/\\1/')
AGENT_NAME=$(echo "$FRONTMATTER" | grep '^agent_name:' | sed 's/agent_name: *//' | sed 's/^"\\(.*\\)"$/\\1/')
TASK_NUMBER=$(echo "$FRONTMATTER" | grep '^task_number:' | sed 's/task_number: *//' | sed 's/^"\\(.*\\)"$/\\1/')
PR_NUMBER=$(echo "$FRONTMATTER" | grep '^pr_number:' | sed 's/pr_number: *//' | sed 's/^"\\(.*\\)"$/\\1/')
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')

# Check if enabled
if [[ "$ENABLED" != "true" ]]; then
  exit 0
fi

# Send notification to coordinator
NOTIFICATION="🤖 Agent ${AGENT_NAME} (Task ${TASK_NUMBER}, PR #${PR_NUMBER}) is idle."

if tmux has-session -t "$COORDINATOR_SESSION" 2>/dev/null; then
  tmux send-keys -t "$COORDINATOR_SESSION" "$NOTIFICATION" Enter
  sleep 0.5
  tmux send-keys -t "$COORDINATOR_SESSION" Enter
fi

exit 0

Key patterns:

  1. Quick exit (line 7-9): Returns immediately if file doesn't exist
  2. Field extraction (lines 11-17): Parses each frontmatter field
  3. Enabled check (lines 19-21): Respects enabled flag
  4. Action based on settings (lines 23-29): Uses coordinator_session to send notification

Creation

File: commands/launch-swarm.md

Settings files are created during swarm launch with:

cat > "$WORKTREE_PATH/.claude/multi-agent-swarm.local.md" < temp.md
mv temp.md ".claude/multi-agent-swarm.local.md"

ralph-wiggum Plugin

Settings File Structure

.claude/ralph-loop.local.md:

---
iteration: 1
max_iterations: 10
completion_promise: "All tests passing and build successful"
started_at: "2025-01-15T14:30:00Z"
---

Fix all the linting errors in the project.
Make sure tests pass after each fix.
Document any changes needed in CLAUDE.md.

How It's Used

File: hooks/stop-hook.sh

Purpose: Prevent session exit and loop Claude's output back as input

Implementation:

#!/bin/bash
set -euo pipefail

RALPH_STATE_FILE=".claude/ralph-loop.local.md"

# Quick exit if no active loop
if [[ ! -f "$RALPH_STATE_FILE" ]]; then
  exit 0
fi

# Parse frontmatter
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$RALPH_STATE_FILE")

# Extract configuration
ITERATION=$(echo "$FRONTMATTER" | grep '^iteration:' | sed 's/iteration: *//')
MAX_ITERATIONS=$(echo "$FRONTMATTER" | grep '^max_iterations:' | sed 's/max_iterations: *//')
COMPLETION_PROMISE=$(echo "$FRONTMATTER" | grep '^completion_promise:' | sed 's/completion_promise: *//' | sed 's/^"\\(.*\\)"$/\\1/')

# Check max iterations
if [[ $MAX_ITERATIONS -gt 0 ]] && [[ $ITERATION -ge $MAX_ITERATIONS ]]; then
  echo "🛑 Ralph loop: Max iterations ($MAX_ITERATIONS) reached."
  rm "$RALPH_STATE_FILE"
  exit 0
fi

# Get transcript and check for completion promise
TRANSCRIPT_PATH=$(echo "$HOOK_INPUT" | jq -r '.transcript_path')
LAST_OUTPUT=$(grep '"role":"assistant"' "$TRANSCRIPT_PATH" | tail -1 | jq -r '.message.content | map(select(.type == "text")) | map(.text) | join("\
")')

# Check for completion
if [[ "$COMPLETION_PROMISE" != "null" ]] && [[ -n "$COMPLETION_PROMISE" ]]; then
  PROMISE_TEXT=$(echo "$LAST_OUTPUT" | perl -0777 -pe 's/.*?<promise>(.*?)<\\/promise>.*/$1/s; s/^\\s+|\\s+$//g')

  if [[ "$PROMISE_TEXT" = "$COMPLETION_PROMISE" ]]; then
    echo "✅ Ralph loop: Detected completion"
    rm "$RALPH_STATE_FILE"
    exit 0
  fi
fi

# Continue loop - increment iteration
NEXT_ITERATION=$((ITERATION + 1))

# Extract prompt from markdown body
PROMPT_TEXT=$(awk '/^---$/{i++; next} i>=2' "$RALPH_STATE_FILE")

# Update iteration counter
TEMP_FILE="${RALPH_STATE_FILE}.tmp.$$"
sed "s/^iteration: .*/iteration: $NEXT_ITERATION/" "$RALPH_STATE_FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$RALPH_STATE_FILE"

# Block exit and feed prompt back
jq -n \\
  --arg prompt "$PROMPT_TEXT" \\
  --arg msg "🔄 Ralph iteration $NEXT_ITERATION" \\
  '{
    "decision": "block",
    "reason": $prompt,
    "systemMessage": $msg
  }'

exit 0

Key patterns:

  1. Quick exit (line 7-9): Skip if not active
  2. Iteration tracking (lines 11-20): Count and enforce max iterations
  3. Promise detection (lines 25-33): Check for completion signal in output
  4. Prompt extraction (line 38): Read markdown body as next prompt
  5. State update (lines 40-43): Increment iteration atomically
  6. Loop continuation (lines 45-53): Block exit and feed prompt back

Creation

File: scripts/setup-ralph-loop.sh

#!/bin/bash
PROMPT="$1"
MAX_ITERATIONS="${2:-0}"
COMPLETION_PROMISE="${3:-}"

# Create state file
cat > ".claude/ralph-loop.local.md" < "$TEMP_FILE"
mv "$TEMP_FILE" "$FILE"

Why: Prevents corruption if process is interrupted.

4. Quote Handling

Both strip surrounding quotes from YAML values:

sed 's/^"\\(.*\\)"$/\\1/'

Why: YAML allows both field: value and field: "value".

5. Error Handling

Both handle missing/corrupt files gracefully:

if [[ ! -f "$FILE" ]]; then
  exit 0  # No error, just not configured
fi

if [[ -z "$CRITICAL_FIELD" ]]; then
  echo "Settings file corrupt" >&2
  rm "$FILE"  # Clean up
  exit 0
fi

Why: Fails gracefully instead of crashing.

Anti-Patterns to Avoid

❌ Hardcoded Paths

# BAD
FILE="/Users/alice/.claude/my-plugin.local.md"

# GOOD
FILE=".claude/my-plugin.local.md"

❌ Unquoted Variables

# BAD
echo $VALUE

# GOOD
echo "$VALUE"

❌ Non-Atomic Updates

# BAD: Can corrupt file if interrupted
sed -i "s/field: .*/field: $VALUE/" "$FILE"

# GOOD: Atomic
TEMP_FILE="${FILE}.tmp.$$"
sed "s/field: .*/field: $VALUE/" "$FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$FILE"

❌ No Default Values

# BAD: Fails if field missing
if [[ $MAX -gt 100 ]]; then
  # MAX might be empty!
fi

# GOOD: Provide default
MAX=${MAX:-10}

❌ Ignoring Edge Cases

# BAD: Assumes exactly 2 --- markers
sed -n '/^---$/,/^---$/{ /^---$/d; p; }'

# GOOD: Handles --- in body
awk '/^---$/{i++; next} i>=2'  # For body

Conclusion

The .claude/plugin-name.local.md pattern provides:

  • Simple, human-readable configuration
  • Version-control friendly (gitignored)
  • Per-project settings
  • Easy parsing with standard bash tools
  • Supports both structured config (YAML) and freeform content (markdown)

Use this pattern for any plugin that needs user-configurable behavior or state persistence.