Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:26:37 +08:00
commit 5fdc9f2c12
67 changed files with 22481 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
---
description: "Create plugin settings file with user preferences"
allowed-tools: ["Write", "AskUserQuestion"]
---
# Create Plugin Settings
This command helps users create a `.claude/my-plugin.local.md` settings file.
## Steps
### Step 1: Ask User for Preferences
Use AskUserQuestion to gather configuration:
```json
{
"questions": [
{
"question": "Enable plugin for this project?",
"header": "Enable Plugin",
"multiSelect": false,
"options": [
{
"label": "Yes",
"description": "Plugin will be active"
},
{
"label": "No",
"description": "Plugin will be disabled"
}
]
},
{
"question": "Validation mode?",
"header": "Mode",
"multiSelect": false,
"options": [
{
"label": "Strict",
"description": "Maximum validation and security checks"
},
{
"label": "Standard",
"description": "Balanced validation (recommended)"
},
{
"label": "Lenient",
"description": "Minimal validation only"
}
]
}
]
}
```
### Step 2: Parse Answers
Extract answers from AskUserQuestion result:
- answers["0"]: enabled (Yes/No)
- answers["1"]: mode (Strict/Standard/Lenient)
### Step 3: Create Settings File
Use Write tool to create `.claude/my-plugin.local.md`:
```markdown
---
enabled: <true if Yes, false if No>
validation_mode: <strict, standard, or lenient>
max_file_size: 1000000
notify_on_errors: true
---
# Plugin Configuration
Your plugin is configured with <mode> validation mode.
To modify settings, edit this file and restart Claude Code.
```
### Step 4: Inform User
Tell the user:
- Settings file created at `.claude/my-plugin.local.md`
- Current configuration summary
- How to edit manually if needed
- Reminder: Restart Claude Code for changes to take effect
- Settings file is gitignored (won't be committed)
## Implementation Notes
Always validate user input before writing:
- Check mode is valid
- Validate numeric fields are numbers
- Ensure paths don't have traversal attempts
- Sanitize any free-text fields

View File

@@ -0,0 +1,159 @@
# Example Plugin Settings File
## Template: Basic Configuration
**.claude/my-plugin.local.md:**
```markdown
---
enabled: true
mode: standard
---
# My Plugin Configuration
Plugin is active in standard mode.
```
## Template: Advanced Configuration
**.claude/my-plugin.local.md:**
```markdown
---
enabled: true
strict_mode: false
max_file_size: 1000000
allowed_extensions: [".js", ".ts", ".tsx"]
enable_logging: true
notification_level: info
retry_attempts: 3
timeout_seconds: 60
custom_path: "/path/to/data"
---
# My Plugin Advanced Configuration
This project uses custom plugin configuration with:
- Standard validation mode
- 1MB file size limit
- JavaScript/TypeScript files allowed
- Info-level logging
- 3 retry attempts
## Additional Notes
Contact @team-lead with questions about this configuration.
```
## Template: Agent State File
**.claude/multi-agent-swarm.local.md:**
```markdown
---
agent_name: database-implementation
task_number: 4.2
pr_number: 5678
coordinator_session: team-leader
enabled: true
dependencies: ["Task 3.5", "Task 4.1"]
additional_instructions: "Use PostgreSQL, not MySQL"
---
# Task Assignment: Database Schema Implementation
Implement the database schema for the new features module.
## Requirements
- Create migration files
- Add indexes for performance
- Write tests for constraints
- Document schema in README
## Success Criteria
- Migrations run successfully
- All tests pass
- PR created with CI green
- Schema documented
## Coordination
Depends on:
- Task 3.5: API endpoint definitions
- Task 4.1: Data model design
Report status to coordinator session 'team-leader'.
```
## Template: Feature Flag Pattern
**.claude/experimental-features.local.md:**
```markdown
---
enabled: true
features:
- ai_suggestions
- auto_formatting
- advanced_refactoring
experimental_mode: false
---
# Experimental Features Configuration
Current enabled features:
- AI-powered code suggestions
- Automatic code formatting
- Advanced refactoring tools
Experimental mode is OFF (stable features only).
```
## Usage in Hooks
These templates can be read by hooks:
```bash
# Check if plugin is configured
if [[ ! -f ".claude/my-plugin.local.md" ]]; then
exit 0 # Not configured, skip hook
fi
# Read settings
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' ".claude/my-plugin.local.md")
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')
# Apply settings
if [[ "$ENABLED" == "true" ]]; then
# Hook is active
# ...
fi
```
## Gitignore
Always add to project `.gitignore`:
```gitignore
# Plugin settings (user-local, not committed)
.claude/*.local.md
.claude/*.local.json
```
## Editing Settings
Users can edit settings files manually:
```bash
# Edit settings
vim .claude/my-plugin.local.md
# Changes take effect after restart
exit # Exit Claude Code
claude # Restart
```
Changes require Claude Code restart - hooks can't be hot-swapped.

View File

@@ -0,0 +1,65 @@
#!/bin/bash
# Example hook that reads plugin settings from .claude/my-plugin.local.md
# Demonstrates the complete pattern for settings-driven hook behavior
set -euo pipefail
# Define settings file path
SETTINGS_FILE=".claude/my-plugin.local.md"
# Quick exit if settings file doesn't exist
if [[ ! -f "$SETTINGS_FILE" ]]; then
# Plugin not configured - use defaults or skip
exit 0
fi
# Parse YAML frontmatter (everything between --- markers)
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$SETTINGS_FILE")
# Extract configuration 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/')
MAX_SIZE=$(echo "$FRONTMATTER" | grep '^max_file_size:' | sed 's/max_file_size: *//')
# Quick exit if disabled
if [[ "$ENABLED" != "true" ]]; then
exit 0
fi
# Read hook input
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
# Apply configured validation
if [[ "$STRICT_MODE" == "true" ]]; then
# Strict mode: apply all checks
if [[ "$file_path" == *".."* ]]; then
echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "Path traversal blocked (strict mode)"}' >&2
exit 2
fi
if [[ "$file_path" == *".env"* ]] || [[ "$file_path" == *"secret"* ]]; then
echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "Sensitive file blocked (strict mode)"}' >&2
exit 2
fi
else
# Standard mode: basic checks only
if [[ "$file_path" == "/etc/"* ]] || [[ "$file_path" == "/sys/"* ]]; then
echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "System path blocked"}' >&2
exit 2
fi
fi
# Check file size if configured
if [[ -n "$MAX_SIZE" ]] && [[ "$MAX_SIZE" =~ ^[0-9]+$ ]]; then
content=$(echo "$input" | jq -r '.tool_input.content // empty')
content_size=${#content}
if [[ $content_size -gt $MAX_SIZE ]]; then
echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "File exceeds configured max size: '"$MAX_SIZE"' bytes"}' >&2
exit 2
fi
fi
# All checks passed
exit 0