mirror of
https://github.com/anthropics/claude-code.git
synced 2026-02-19 04:27:33 -08:00
Compare commits
1 Commits
ci/update-
...
claude/sla
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
411f17c228 |
@@ -12,6 +12,7 @@ Learn more in the [official plugins documentation](https://docs.claude.com/en/do
|
||||
|
||||
| Name | Description | Contents |
|
||||
|------|-------------|----------|
|
||||
| [accept-with-feedback](./accept-with-feedback/) | Accept permission requests with feedback - provide guidance to Claude when approving operations | **Commands:** `/accept-feedback`, `/configure-feedback` - Set one-time or persistent feedback<br>**Hook:** PermissionRequest - Intercepts permissions to add user guidance |
|
||||
| [agent-sdk-dev](./agent-sdk-dev/) | Development kit for working with the Claude Agent SDK | **Command:** `/new-sdk-app` - Interactive setup for new Agent SDK projects<br>**Agents:** `agent-sdk-verifier-py`, `agent-sdk-verifier-ts` - Validate SDK applications against best practices |
|
||||
| [claude-opus-4-5-migration](./claude-opus-4-5-migration/) | Migrate code and prompts from Sonnet 4.x and Opus 4.1 to Opus 4.5 | **Skill:** `claude-opus-4-5-migration` - Automated migration of model strings, beta headers, and prompt adjustments |
|
||||
| [code-review](./code-review/) | Automated PR code review using multiple specialized agents with confidence-based scoring to filter false positives | **Command:** `/code-review` - Automated PR review workflow<br>**Agents:** 5 parallel Sonnet agents for CLAUDE.md compliance, bug detection, historical context, PR history, and code comments |
|
||||
|
||||
9
plugins/accept-with-feedback/.claude-plugin/plugin.json
Normal file
9
plugins/accept-with-feedback/.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "accept-with-feedback",
|
||||
"version": "1.0.0",
|
||||
"description": "Accept permission requests with feedback - provide guidance to Claude when approving operations",
|
||||
"author": {
|
||||
"name": "Anthropic",
|
||||
"email": "support@anthropic.com"
|
||||
}
|
||||
}
|
||||
151
plugins/accept-with-feedback/README.md
Normal file
151
plugins/accept-with-feedback/README.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# Accept with Feedback
|
||||
|
||||
A Claude Code plugin that lets you approve operations while providing guidance to Claude. Instead of just accepting or rejecting permission requests, you can accept *with feedback* - approving the operation while giving Claude additional context or instructions.
|
||||
|
||||
## Why?
|
||||
|
||||
Sometimes you want to approve an operation but also want to guide Claude's behavior:
|
||||
|
||||
- "Yes, edit that file, but make sure to add error handling"
|
||||
- "Okay to run those tests, but skip the slow integration tests"
|
||||
- "Go ahead and commit, but use conventional commit format"
|
||||
|
||||
This plugin bridges the gap between simple approval and rejection-with-feedback.
|
||||
|
||||
## Installation
|
||||
|
||||
This plugin is included in the Claude Code repository. Enable it in your settings or use:
|
||||
|
||||
```bash
|
||||
claude /plugin install accept-with-feedback
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### One-time feedback
|
||||
|
||||
Use the `/accept-feedback` command to queue feedback for the next permission request:
|
||||
|
||||
```
|
||||
/accept-feedback Make sure to preserve backwards compatibility
|
||||
```
|
||||
|
||||
When Claude next asks for permission (e.g., to edit a file), the operation will be automatically approved and Claude will receive your guidance as a system message.
|
||||
|
||||
### Persistent feedback rules
|
||||
|
||||
Create rules that automatically provide feedback for certain types of operations. Add configuration to `.claude/accept-feedback.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"conditions": {
|
||||
"file_path": ".py"
|
||||
},
|
||||
"feedback": "Follow PEP 8 style and add type hints to all functions."
|
||||
},
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"conditions": {
|
||||
"command": "npm"
|
||||
},
|
||||
"feedback": "Use --legacy-peer-deps if you encounter peer dependency issues."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Use `/configure-feedback` for an interactive configuration experience.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Rule properties
|
||||
|
||||
| Property | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `matcher` | Tool name pattern | `"Edit"`, `"Write\|Edit"`, `"*"` |
|
||||
| `conditions` | Optional filters on tool input | `{"file_path": ".ts"}` |
|
||||
| `feedback` | Guidance message for Claude | `"Add JSDoc comments"` |
|
||||
|
||||
### Configuration locations
|
||||
|
||||
- **User-level**: `~/.claude/accept-feedback.json`
|
||||
- **Project-level**: `.claude/accept-feedback.json` (takes precedence)
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/accept-feedback <message>` | Queue feedback for the next permission request |
|
||||
| `/configure-feedback` | Interactive configuration of persistent rules |
|
||||
|
||||
## How it works
|
||||
|
||||
1. The plugin uses a `PermissionRequest` hook to intercept permission requests
|
||||
2. When a permission request occurs:
|
||||
- If there's pending feedback (from `/accept-feedback`), approve with that feedback
|
||||
- If a configured rule matches, approve with the rule's feedback
|
||||
- Otherwise, let the normal permission flow proceed
|
||||
3. Feedback is sent to Claude as a system message, providing guidance for the operation
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: One-time guidance
|
||||
|
||||
```
|
||||
You: /accept-feedback Please add comprehensive error handling
|
||||
|
||||
Claude: I'll edit src/api.ts to add the new endpoint...
|
||||
[Permission automatically approved with your feedback]
|
||||
|
||||
Claude: I've added the endpoint with try-catch blocks and proper error responses...
|
||||
```
|
||||
|
||||
### Example 2: Persistent Python style rules
|
||||
|
||||
`.claude/accept-feedback.json`:
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"conditions": {
|
||||
"file_path": ".py"
|
||||
},
|
||||
"feedback": "Use Google-style docstrings and add type hints to all function signatures."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Every time Claude edits a Python file, it receives this style guidance.
|
||||
|
||||
### Example 3: Git workflow rules
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"conditions": {
|
||||
"command": "git commit"
|
||||
},
|
||||
"feedback": "Use conventional commit format: type(scope): description"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Use specific matchers to avoid unnecessary approvals
|
||||
- Conditions use substring matching - `".py"` matches any path containing `.py`
|
||||
- Combine with other permission management for a comprehensive workflow
|
||||
- Feedback is visible in the conversation, so Claude can reference it
|
||||
|
||||
## Related
|
||||
|
||||
- Rejecting with feedback: Built into Claude Code's plan rejection flow
|
||||
- Permission hooks: See the [hook development guide](../plugin-dev/skills/hook-development/SKILL.md)
|
||||
63
plugins/accept-with-feedback/commands/accept-feedback.md
Normal file
63
plugins/accept-with-feedback/commands/accept-feedback.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
description: Set feedback to provide when accepting the next permission request
|
||||
argument_name: feedback
|
||||
---
|
||||
|
||||
# Accept with Feedback
|
||||
|
||||
You are helping the user set feedback that will be automatically provided to Claude when the next permission request is approved.
|
||||
|
||||
## What the user wants
|
||||
|
||||
The user wants to approve an upcoming operation but also provide guidance or feedback to Claude. This feedback will:
|
||||
1. Automatically approve the next permission request
|
||||
2. Send the feedback message to Claude as guidance
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Parse the user's feedback from the argument: `$ARGUMENTS`
|
||||
|
||||
2. If feedback was provided, save it for the next permission request:
|
||||
- Create/update the file `~/.claude/pending-accept-feedback.json`
|
||||
- Store the feedback with the current session ID
|
||||
|
||||
3. Confirm to the user that their feedback has been queued
|
||||
|
||||
## Saving the feedback
|
||||
|
||||
Use this Python code to save the pending feedback:
|
||||
|
||||
```python
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
feedback = """$ARGUMENTS"""
|
||||
session_id = os.environ.get("CLAUDE_SESSION_ID", "default")
|
||||
|
||||
pending_file = Path.home() / ".claude" / "pending-accept-feedback.json"
|
||||
pending_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
existing = json.loads(pending_file.read_text()) if pending_file.exists() else {}
|
||||
except:
|
||||
existing = {}
|
||||
|
||||
existing[session_id] = {
|
||||
"message": feedback,
|
||||
"one_time": True
|
||||
}
|
||||
|
||||
pending_file.write_text(json.dumps(existing, indent=2))
|
||||
print(f"Feedback queued for next permission request.")
|
||||
```
|
||||
|
||||
## Example usage
|
||||
|
||||
User runs: `/accept-feedback Make sure to add error handling`
|
||||
|
||||
Then when Claude asks for permission to edit a file, the operation is automatically approved and Claude receives the guidance: "Make sure to add error handling"
|
||||
|
||||
## Response
|
||||
|
||||
After saving, confirm: "Your feedback has been queued. The next permission request will be automatically approved, and Claude will receive your guidance."
|
||||
80
plugins/accept-with-feedback/commands/configure-feedback.md
Normal file
80
plugins/accept-with-feedback/commands/configure-feedback.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
description: Configure persistent feedback rules for accept-with-feedback
|
||||
---
|
||||
|
||||
# Configure Accept-with-Feedback Rules
|
||||
|
||||
You are helping the user configure persistent feedback rules that automatically provide guidance to Claude when certain operations are approved.
|
||||
|
||||
## Configuration file location
|
||||
|
||||
Rules are stored in `.claude/accept-feedback.json` in either:
|
||||
- User's home directory (`~/.claude/accept-feedback.json`) for global rules
|
||||
- Project directory (`.claude/accept-feedback.json`) for project-specific rules
|
||||
|
||||
Project rules take precedence over user rules.
|
||||
|
||||
## Configuration format
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"conditions": {
|
||||
"file_path": ".py"
|
||||
},
|
||||
"feedback": "Ensure all Python code follows PEP 8 style guidelines and includes type hints."
|
||||
},
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"conditions": {
|
||||
"command": "git"
|
||||
},
|
||||
"feedback": "Use conventional commit format for commit messages."
|
||||
},
|
||||
{
|
||||
"matcher": "*",
|
||||
"feedback": "Please explain your reasoning before making changes."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Rule properties
|
||||
|
||||
- **matcher**: Tool name pattern (e.g., "Edit", "Write|Edit", "*" for all)
|
||||
- **conditions**: Optional key-value pairs to match against tool input
|
||||
- **feedback**: The guidance message to send to Claude when this rule matches
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Ask the user what kind of feedback rules they want to configure
|
||||
2. Help them create appropriate rules based on their needs
|
||||
3. Save the configuration to the appropriate location
|
||||
|
||||
## Common use cases
|
||||
|
||||
1. **Code style guidance**: Provide style guidelines when editing specific file types
|
||||
2. **Git workflow**: Add commit message format requirements for git operations
|
||||
3. **Safety reminders**: Add warnings when working with sensitive files
|
||||
4. **Project conventions**: Enforce project-specific patterns and practices
|
||||
|
||||
## Example interaction
|
||||
|
||||
User: "I want to always remind Claude to add tests when editing Python files"
|
||||
|
||||
You would create:
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"conditions": {
|
||||
"file_path": ".py"
|
||||
},
|
||||
"feedback": "Remember to add or update tests for any code changes."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
152
plugins/accept-with-feedback/hooks/accept_with_feedback.py
Normal file
152
plugins/accept-with-feedback/hooks/accept_with_feedback.py
Normal file
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Accept with Feedback Hook for Claude Code
|
||||
|
||||
This hook intercepts permission requests and allows users to provide feedback
|
||||
when accepting operations. The feedback is passed to Claude as a system message,
|
||||
giving users a way to provide guidance while still approving the operation.
|
||||
|
||||
Usage:
|
||||
1. Set pending feedback: /accept-feedback "your guidance here"
|
||||
2. When a permission prompt appears, if pending feedback exists:
|
||||
- The operation is automatically approved
|
||||
- Your feedback is sent to Claude as guidance
|
||||
3. Or configure always-on feedback rules in .claude/accept-feedback.json
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_config_paths():
|
||||
"""Get paths for config and state files."""
|
||||
claude_dir = Path.home() / ".claude"
|
||||
project_dir = Path(os.environ.get("CLAUDE_PROJECT_DIR", "."))
|
||||
|
||||
return {
|
||||
"user_config": claude_dir / "accept-feedback.json",
|
||||
"project_config": project_dir / ".claude" / "accept-feedback.json",
|
||||
"pending_feedback": claude_dir / "pending-accept-feedback.json",
|
||||
}
|
||||
|
||||
|
||||
def load_json_file(path):
|
||||
"""Load JSON from file, return empty dict if not found."""
|
||||
try:
|
||||
if path.exists():
|
||||
with open(path, "r") as f:
|
||||
return json.load(f)
|
||||
except (json.JSONDecodeError, IOError):
|
||||
pass
|
||||
return {}
|
||||
|
||||
|
||||
def get_pending_feedback(session_id):
|
||||
"""Get pending feedback for this session and clear it."""
|
||||
paths = get_config_paths()
|
||||
pending_file = paths["pending_feedback"]
|
||||
|
||||
pending = load_json_file(pending_file)
|
||||
|
||||
# Check for session-specific pending feedback
|
||||
if session_id in pending:
|
||||
feedback = pending[session_id]
|
||||
# Clear the pending feedback after use
|
||||
del pending[session_id]
|
||||
try:
|
||||
if pending:
|
||||
with open(pending_file, "w") as f:
|
||||
json.dump(pending, f)
|
||||
else:
|
||||
pending_file.unlink(missing_ok=True)
|
||||
except IOError:
|
||||
pass
|
||||
return feedback.get("message"), feedback.get("one_time", True)
|
||||
|
||||
return None, True
|
||||
|
||||
|
||||
def get_configured_feedback(tool_name, tool_input):
|
||||
"""Get feedback configured for this tool type."""
|
||||
paths = get_config_paths()
|
||||
|
||||
# Load both user and project configs
|
||||
user_config = load_json_file(paths["user_config"])
|
||||
project_config = load_json_file(paths["project_config"])
|
||||
|
||||
# Project config takes precedence
|
||||
config = {**user_config, **project_config}
|
||||
|
||||
rules = config.get("rules", [])
|
||||
|
||||
for rule in rules:
|
||||
# Check if rule matches this tool
|
||||
matcher = rule.get("matcher", "*")
|
||||
if matcher == "*" or tool_name in matcher.split("|"):
|
||||
# Check conditions if specified
|
||||
conditions = rule.get("conditions", {})
|
||||
matches = True
|
||||
|
||||
for key, pattern in conditions.items():
|
||||
value = str(tool_input.get(key, ""))
|
||||
if pattern not in value:
|
||||
matches = False
|
||||
break
|
||||
|
||||
if matches:
|
||||
return rule.get("feedback")
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
"""Main hook function."""
|
||||
# Read input from stdin
|
||||
try:
|
||||
raw_input = sys.stdin.read()
|
||||
input_data = json.loads(raw_input)
|
||||
except json.JSONDecodeError:
|
||||
# Can't parse input, don't interfere
|
||||
sys.exit(0)
|
||||
|
||||
session_id = input_data.get("session_id", "default")
|
||||
tool_name = input_data.get("tool_name", "")
|
||||
tool_input = input_data.get("tool_input", {})
|
||||
|
||||
# Check for pending feedback first (from /accept-feedback command)
|
||||
pending_message, _ = get_pending_feedback(session_id)
|
||||
|
||||
if pending_message:
|
||||
# We have pending feedback - approve with the feedback as system message
|
||||
result = {
|
||||
"hookSpecificOutput": {
|
||||
"permissionDecision": "allow"
|
||||
},
|
||||
"systemMessage": f"[User Feedback on Approval]: {pending_message}"
|
||||
}
|
||||
print(json.dumps(result))
|
||||
sys.exit(0)
|
||||
|
||||
# Check for configured feedback rules
|
||||
configured_feedback = get_configured_feedback(tool_name, tool_input)
|
||||
|
||||
if configured_feedback:
|
||||
# We have configured feedback for this tool type
|
||||
result = {
|
||||
"hookSpecificOutput": {
|
||||
"permissionDecision": "allow"
|
||||
},
|
||||
"systemMessage": f"[User Guidance]: {configured_feedback}"
|
||||
}
|
||||
print(json.dumps(result))
|
||||
sys.exit(0)
|
||||
|
||||
# No feedback configured - don't interfere with the normal permission flow
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
17
plugins/accept-with-feedback/hooks/hooks.json
Normal file
17
plugins/accept-with-feedback/hooks/hooks.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"description": "Accept with feedback - allows users to provide guidance when approving tool permissions",
|
||||
"hooks": {
|
||||
"PermissionRequest": [
|
||||
{
|
||||
"matcher": "*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/accept_with_feedback.py",
|
||||
"timeout": 300
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user