mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-02-03 08:53:37 +00:00
Compare commits
1 Commits
daisy/caff
...
claude/cir
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15aab95740 |
@@ -328,17 +328,6 @@
|
|||||||
"category": "productivity",
|
"category": "productivity",
|
||||||
"homepage": "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-simplifier"
|
"homepage": "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-simplifier"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "caffeinate",
|
|
||||||
"description": "Prevents blocking sleep commands by intercepting them and prompting Claude to use background execution instead. Keeps your session responsive during long-running operations.",
|
|
||||||
"author": {
|
|
||||||
"name": "Anthropic",
|
|
||||||
"email": "support@anthropic.com"
|
|
||||||
},
|
|
||||||
"source": "./plugins/caffeinate",
|
|
||||||
"category": "productivity",
|
|
||||||
"homepage": "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/caffeinate"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "explanatory-output-style",
|
"name": "explanatory-output-style",
|
||||||
"description": "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)",
|
"description": "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)",
|
||||||
@@ -567,6 +556,16 @@
|
|||||||
"url": "https://github.com/huggingface/skills.git"
|
"url": "https://github.com/huggingface/skills.git"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/huggingface/skills.git"
|
"homepage": "https://github.com/huggingface/skills.git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "circleback",
|
||||||
|
"description": "Circleback conversational context integration. Search and access meetings, emails, calendar events, and more.",
|
||||||
|
"category": "productivity",
|
||||||
|
"source": {
|
||||||
|
"source": "url",
|
||||||
|
"url": "https://github.com/circlebackai/claude-code-plugin.git"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/circlebackai/claude-code-plugin.git"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "caffeinate",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"description": "Blocks sleep commands and reminds Claude to use background tasks instead",
|
|
||||||
"author": {
|
|
||||||
"name": "Anthropic",
|
|
||||||
"email": "support@anthropic.com"
|
|
||||||
},
|
|
||||||
"keywords": ["productivity", "hooks", "bash", "background-tasks"]
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
# Caffeinate
|
|
||||||
|
|
||||||
A Claude Code plugin that blocks `sleep` commands and reminds Claude to use background tasks instead.
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
When Claude uses `sleep` commands in Bash, it blocks the session unnecessarily. This plugin intercepts these commands and suggests using proper async patterns like:
|
|
||||||
|
|
||||||
- `run_in_background: true` parameter for long-running commands
|
|
||||||
- Polling for conditions instead of sleeping
|
|
||||||
- Proper async/background task patterns
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# From the plugin directory
|
|
||||||
claude --plugin-dir /path/to/caffeinate
|
|
||||||
```
|
|
||||||
|
|
||||||
Or copy to your project's `.claude-plugin/` directory.
|
|
||||||
|
|
||||||
## What Gets Blocked
|
|
||||||
|
|
||||||
| Command | Blocked? | Reason |
|
|
||||||
|---------|----------|--------|
|
|
||||||
| `sleep 5` | Yes | Direct sleep command |
|
|
||||||
| `sleep $TIMEOUT` | Yes | Sleep with variable |
|
|
||||||
| `echo "test" && sleep 5` | Yes | Sleep after separator, outside quotes |
|
|
||||||
| `cmd; sleep 10` | Yes | Sleep after semicolon |
|
|
||||||
| `echo "sleep 8 hours"` | No | Sleep is inside quotes (not a command) |
|
|
||||||
| `echo "foo && sleep 5"` | No | Entire sleep pattern is in a string |
|
|
||||||
|
|
||||||
## How It Works
|
|
||||||
|
|
||||||
The plugin uses a `PreToolUse` hook on the `Bash` tool to:
|
|
||||||
|
|
||||||
1. Check if commands start with `sleep`
|
|
||||||
2. Detect `sleep` after command separators (`&&`, `||`, `;`, `|`)
|
|
||||||
3. Use quote-counting to avoid false positives when `sleep` appears inside strings
|
|
||||||
|
|
||||||
## Alternatives to Sleep
|
|
||||||
|
|
||||||
Instead of:
|
|
||||||
```bash
|
|
||||||
sleep 5 && check_status
|
|
||||||
```
|
|
||||||
|
|
||||||
Use background execution:
|
|
||||||
```bash
|
|
||||||
# Run in background with run_in_background: true
|
|
||||||
long_running_command
|
|
||||||
```
|
|
||||||
|
|
||||||
Or poll for conditions:
|
|
||||||
```bash
|
|
||||||
# Poll for a file to exist
|
|
||||||
while [ ! -f /tmp/ready ]; do :; done
|
|
||||||
```
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"description": "Blocks sleep commands and reminds Claude to use background tasks",
|
|
||||||
"hooks": {
|
|
||||||
"PreToolUse": [
|
|
||||||
{
|
|
||||||
"matcher": "Bash",
|
|
||||||
"hooks": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check-sleep.sh",
|
|
||||||
"timeout": 5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Caffeinate hook: Blocks sleep commands and suggests background tasks
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
input=$(cat)
|
|
||||||
command=$(echo "$input" | jq -r '.tool_input.command // empty')
|
|
||||||
|
|
||||||
if [[ -z "$command" ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Allow sleep if run_in_background is true - that's the whole point!
|
|
||||||
run_in_bg=$(echo "$input" | jq -r '.tool_input.run_in_background // false')
|
|
||||||
if [[ "$run_in_bg" == "true" ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
block_message='ACTION REQUIRED: Your sleep command was blocked. You MUST now call Bash again with the SAME command but add the parameter run_in_background: true. Do this immediately in your next tool call. Do not explain or apologize - just retry with run_in_background: true.'
|
|
||||||
|
|
||||||
output_block() {
|
|
||||||
# Output JSON to stdout for blocking decision
|
|
||||||
# Output message to stderr to feed back to Claude
|
|
||||||
cat << EOF
|
|
||||||
{
|
|
||||||
"hookSpecificOutput": {
|
|
||||||
"hookEventName": "PreToolUse",
|
|
||||||
"permissionDecision": "deny",
|
|
||||||
"permissionDecisionReason": "$block_message"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove all quoted strings to avoid false positives
|
|
||||||
# Replace single and double quoted strings with placeholder
|
|
||||||
cmd_no_quotes=$(echo "$command" | sed -E "s/\"[^\"]*\"//g; s/'[^']*'//g")
|
|
||||||
|
|
||||||
# Check for sleep command patterns in the de-quoted command
|
|
||||||
# Pattern 1: Command starts with sleep
|
|
||||||
if [[ "$cmd_no_quotes" =~ (^|[[:space:]])sleep[[:space:]]+[0-9] ]]; then
|
|
||||||
output_block
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Pattern 2: sleep after any common separator (&&, ||, ;, |, do, then)
|
|
||||||
if [[ "$cmd_no_quotes" =~ (\&\&|;\||[[:space:]]do[[:space:]]|[[:space:]]then[[:space:]])[[:space:]]*sleep[[:space:]] ]]; then
|
|
||||||
output_block
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Pattern 3: Simple contains check - if "sleep " followed by number appears anywhere
|
|
||||||
if [[ "$cmd_no_quotes" =~ sleep[[:space:]]+[0-9] ]]; then
|
|
||||||
output_block
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Pattern 4: sleep with variable like $TIMEOUT or ${DELAY}
|
|
||||||
if [[ "$cmd_no_quotes" =~ sleep[[:space:]]+\$ ]]; then
|
|
||||||
output_block
|
|
||||||
fi
|
|
||||||
|
|
||||||
# No sleep command detected - allow
|
|
||||||
exit 0
|
|
||||||
Reference in New Issue
Block a user