Add skills, learnings & memory updates (2026-01-26)
- New skills: clawddocs, claude-code-usage, summarize, homeassistant, humanizer, self-improving-agent - Add .learnings/ for self-improvement tracking - Document proaktive cron config (LRN-20260126-001) - Update USER.md: Löchgau as former residence - Update TOOLS.md: Peekaboo workaround - Memory files for 2026-01-25 and 2026-01-26
This commit is contained in:
7
skills/claude-code-usage/.clawdhub/origin.json
Normal file
7
skills/claude-code-usage/.clawdhub/origin.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"registry": "https://clawdhub.com",
|
||||
"slug": "claude-code-usage",
|
||||
"installedVersion": "1.2.0",
|
||||
"installedAt": 1769382253951
|
||||
}
|
||||
77
skills/claude-code-usage/CRON_SETUP.md
Normal file
77
skills/claude-code-usage/CRON_SETUP.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Setting Up Automated Monitoring
|
||||
|
||||
## Option 1: Add via Clawdbot Config (Recommended)
|
||||
|
||||
Add this to your Clawdbot Gateway config (`~/.clawdbot/clawdbot.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"cron": {
|
||||
"jobs": [
|
||||
{
|
||||
"name": "claude-usage-monitor",
|
||||
"schedule": "*/30 * * * *",
|
||||
"sessionTarget": "telegram:YOUR_CHAT_ID",
|
||||
"payload": {
|
||||
"kind": "exec",
|
||||
"command": "/Users/ali/clawd/skills/claude-code-usage/scripts/monitor-usage.sh"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `YOUR_CHAT_ID` with your Telegram chat ID (usually your phone number).
|
||||
|
||||
Then restart Clawdbot:
|
||||
```bash
|
||||
clawdbot daemon restart
|
||||
```
|
||||
|
||||
## Option 2: System Cron (Alternative)
|
||||
|
||||
Add to your system crontab:
|
||||
|
||||
```bash
|
||||
crontab -e
|
||||
```
|
||||
|
||||
Add this line:
|
||||
```
|
||||
*/30 * * * * /Users/ali/clawd/skills/claude-code-usage/scripts/monitor-usage.sh > /tmp/claude-monitor.log 2>&1
|
||||
```
|
||||
|
||||
**Note:** System cron won't send Telegram notifications directly. You'll need to check `/tmp/claude-monitor.log` for reset notifications.
|
||||
|
||||
## Option 3: Manual Testing
|
||||
|
||||
Test the monitor anytime:
|
||||
```bash
|
||||
/Users/ali/clawd/skills/claude-code-usage/scripts/monitor-usage.sh
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
Check if monitoring is working:
|
||||
```bash
|
||||
# View state file
|
||||
cat /tmp/claude-usage-state.json
|
||||
|
||||
# View last check time
|
||||
cat /tmp/claude-usage-state.json | grep last_check
|
||||
```
|
||||
|
||||
## Notification Format
|
||||
|
||||
When a reset is detected, you'll receive:
|
||||
|
||||
```
|
||||
🎉 Claude Code Session Reset!
|
||||
|
||||
⏱️ Your 5-hour quota has reset
|
||||
📊 Usage: 2%
|
||||
⏰ Next reset: 4h 58m
|
||||
|
||||
Fresh usage available! 🦞
|
||||
```
|
||||
86
skills/claude-code-usage/README.md
Normal file
86
skills/claude-code-usage/README.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Claude Code Usage Skill
|
||||
|
||||
Check your Claude Code OAuth API usage limits directly from Clawdbot.
|
||||
|
||||
## Features
|
||||
|
||||
- 📊 Session (5-hour) and Weekly (7-day) utilization tracking
|
||||
- 🎨 Beautiful progress bars with color-coded status indicators
|
||||
- ⚡ Smart caching (60s default) to avoid API spam
|
||||
- 📤 JSON output for scripting
|
||||
- 🦞 Telegram-friendly formatting
|
||||
- 🔔 **NEW v1.1.0**: Automated monitoring with reset notifications
|
||||
|
||||
## Quick Test
|
||||
|
||||
```bash
|
||||
cd /Users/ali/clawd/skills/claude-code-usage
|
||||
./scripts/claude-usage.sh
|
||||
```
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
🦞 Claude Code Usage
|
||||
|
||||
⏱️ Session (5h): 🟢 █░░░░░░░░░ 18%
|
||||
Resets in: 2h 48m
|
||||
|
||||
📅 Weekly (7d): 🟢 ░░░░░░░░░░ 2%
|
||||
Resets in: 6d 21h
|
||||
```
|
||||
|
||||
## Usage in Clawdbot
|
||||
|
||||
Just ask:
|
||||
- "How much Claude usage do I have left?"
|
||||
- "Check my Claude Code limits"
|
||||
- "What's my Claude quota?"
|
||||
|
||||
The skill automatically triggers and provides a formatted response.
|
||||
|
||||
## Automated Monitoring (v1.2.0+)
|
||||
|
||||
### Session Refresh Reminders (Recommended)
|
||||
|
||||
Get notified exactly when your 5-hour session quota refreshes!
|
||||
|
||||
**One-command setup:**
|
||||
```bash
|
||||
cd /Users/ali/clawd/skills/claude-code-usage
|
||||
./scripts/session-reminder.sh
|
||||
```
|
||||
|
||||
This creates a self-scheduling chain that:
|
||||
- Checks when your session refreshes
|
||||
- Schedules the next reminder for that exact time
|
||||
- Notifies you automatically every 5 hours
|
||||
- Runs forever with zero maintenance
|
||||
|
||||
### Reset Detection (Alternative)
|
||||
|
||||
Alternatively, monitor for quota resets by polling:
|
||||
|
||||
```bash
|
||||
./scripts/monitor-usage.sh # Test once
|
||||
./scripts/setup-monitoring.sh # Setup automated polling
|
||||
```
|
||||
|
||||
See `SKILL.md` for detailed comparison and configuration options.
|
||||
|
||||
## Publishing to ClawdHub
|
||||
|
||||
To share with the community:
|
||||
|
||||
```bash
|
||||
cd /Users/ali/clawd/skills
|
||||
clawdhub publish claude-code-usage \
|
||||
--slug claude-code-usage \
|
||||
--name "Claude Code Usage" \
|
||||
--version 1.0.0 \
|
||||
--changelog "Initial release: Session & weekly usage tracking with beautiful formatting"
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
Created for Clawdbot by RZA 🦞
|
||||
251
skills/claude-code-usage/SKILL.md
Normal file
251
skills/claude-code-usage/SKILL.md
Normal file
@@ -0,0 +1,251 @@
|
||||
---
|
||||
name: claude-code-usage
|
||||
description: Check Claude Code OAuth usage limits (session & weekly quotas). Use when user asks about Claude Code usage, remaining limits, rate limits, or how much Claude usage they have left. Includes automated session refresh reminders and reset detection monitoring.
|
||||
metadata:
|
||||
clawdbot:
|
||||
emoji: "📊"
|
||||
os:
|
||||
- darwin
|
||||
- linux
|
||||
requires:
|
||||
bins:
|
||||
- curl
|
||||
---
|
||||
|
||||
# Claude Code Usage
|
||||
|
||||
Check your Claude Code OAuth API usage limits for both session (5-hour) and weekly (7-day) windows.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
cd {baseDir}
|
||||
./scripts/claude-usage.sh
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Default: show cached usage (if fresh)
|
||||
./scripts/claude-usage.sh
|
||||
|
||||
# Force refresh from API
|
||||
./scripts/claude-usage.sh --fresh
|
||||
|
||||
# JSON output
|
||||
./scripts/claude-usage.sh --json
|
||||
|
||||
# Custom cache TTL
|
||||
./scripts/claude-usage.sh --cache-ttl 300
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
**Text format** (default):
|
||||
```
|
||||
🦞 Claude Code Usage
|
||||
|
||||
⏱️ Session (5h): 🟢 ████░░░░░░ 40%
|
||||
Resets in: 2h 15m
|
||||
|
||||
📅 Weekly (7d): 🟡 ██████░░░░ 60%
|
||||
Resets in: 3d 8h
|
||||
```
|
||||
|
||||
**JSON format** (`--json`):
|
||||
```json
|
||||
{
|
||||
"session": {
|
||||
"utilization": 40,
|
||||
"resets_in": "2h 15m",
|
||||
"resets_at": "2026-01-19T22:15:00Z"
|
||||
},
|
||||
"weekly": {
|
||||
"utilization": 60,
|
||||
"resets_in": "3d 8h",
|
||||
"resets_at": "2026-01-22T04:00:00Z"
|
||||
},
|
||||
"cached_at": "2026-01-19T20:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- 📊 **Session limit** (5-hour window) - Short-term rate limit
|
||||
- 📅 **Weekly limit** (7-day window) - Long-term rate limit
|
||||
- ⚡ **Smart caching** - 60-second cache to avoid API spam
|
||||
- 🎨 **Beautiful output** - Progress bars, emojis, color-coded status
|
||||
- 🔄 **Force refresh** - `--fresh` flag to bypass cache
|
||||
- 📤 **JSON output** - Machine-readable format
|
||||
- 🔔 **Automated monitoring** - Get notified when quotas reset
|
||||
|
||||
## Status Indicators
|
||||
|
||||
- 🟢 **Green** - 0-50% usage (healthy)
|
||||
- 🟡 **Yellow** - 51-80% usage (moderate)
|
||||
- 🔴 **Red** - 81-100% usage (high/critical)
|
||||
|
||||
## Requirements
|
||||
|
||||
- **macOS**: Uses Keychain to access Claude Code credentials
|
||||
- **Linux**: Uses `secret-tool` for credential storage
|
||||
- **Credentials**: Must have Claude Code CLI authenticated
|
||||
|
||||
## How It Works
|
||||
|
||||
1. Retrieves OAuth token from system keychain
|
||||
2. Queries `api.anthropic.com/api/oauth/usage` with OAuth bearer token
|
||||
3. Parses `five_hour` and `seven_day` utilization metrics
|
||||
4. Calculates time remaining until reset
|
||||
5. Formats output with progress bars and status indicators
|
||||
6. Caches result for 60 seconds (configurable)
|
||||
|
||||
## Cache
|
||||
|
||||
Default cache: `/tmp/claude-usage-cache` (60s TTL)
|
||||
|
||||
Override:
|
||||
```bash
|
||||
CACHE_FILE=/tmp/my-cache CACHE_TTL=300 ./scripts/claude-usage.sh
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
**Check usage before starting work:**
|
||||
```bash
|
||||
./scripts/claude-usage.sh --fresh
|
||||
```
|
||||
|
||||
**Integrate with statusline:**
|
||||
```bash
|
||||
usage=$(./scripts/claude-usage.sh | grep "Session" | awk '{print $NF}')
|
||||
echo "Session: $usage"
|
||||
```
|
||||
|
||||
**Get JSON for monitoring:**
|
||||
```bash
|
||||
./scripts/claude-usage.sh --json | jq '.session.utilization'
|
||||
```
|
||||
|
||||
## Automated Monitoring
|
||||
|
||||
### Session Refresh Reminders (Recommended)
|
||||
|
||||
Get notified exactly when your 5-hour session quota refreshes!
|
||||
|
||||
**Quick Setup:**
|
||||
```bash
|
||||
./scripts/session-reminder.sh
|
||||
```
|
||||
|
||||
This creates a **self-scheduling chain** of cron jobs that:
|
||||
1. Checks your current session expiry time
|
||||
2. Schedules the next reminder for when your session refreshes
|
||||
3. Notifies you with current usage stats
|
||||
4. Auto-removes itself (the new cron takes over)
|
||||
|
||||
**What You'll Get:**
|
||||
```
|
||||
🔄 Claude Code Session Status
|
||||
|
||||
⏱️ Current usage: 44%
|
||||
⏰ Next refresh: 2h 15m
|
||||
|
||||
Your 5-hour quota will reset soon! 🦞
|
||||
|
||||
✅ Next reminder scheduled for: Jan 22 at 01:22 AM
|
||||
```
|
||||
|
||||
**How It Works:**
|
||||
- Each reminder runs `claude-usage.sh` to find the exact session reset time
|
||||
- Schedules a one-time cron for that exact moment
|
||||
- Repeats every 5 hours automatically
|
||||
- Self-correcting if session times ever drift
|
||||
|
||||
**Benefits:**
|
||||
- ✅ Accurate to the minute
|
||||
- ✅ No manual scheduling needed
|
||||
- ✅ Adapts to your actual usage patterns
|
||||
- ✅ Minimal API calls (only when needed)
|
||||
|
||||
### Reset Detection Monitor (Alternative)
|
||||
|
||||
Get automatic notifications when your Claude Code quotas reset by polling usage.
|
||||
|
||||
**Quick Setup:**
|
||||
```bash
|
||||
# Test once
|
||||
./scripts/monitor-usage.sh
|
||||
|
||||
# Setup automated monitoring (runs every 30 minutes)
|
||||
./scripts/setup-monitoring.sh
|
||||
```
|
||||
|
||||
Or add via Clawdbot directly:
|
||||
```bash
|
||||
# Check every 30 minutes
|
||||
clawdbot cron add --cron "*/30 * * * *" \
|
||||
--message "cd /Users/ali/clawd/skills/claude-code-usage && ./scripts/monitor-usage.sh" \
|
||||
--name "Claude Code Usage Monitor" \
|
||||
--session isolated --deliver --channel telegram
|
||||
```
|
||||
|
||||
**What You'll Get:**
|
||||
```
|
||||
🎉 Claude Code Session Reset!
|
||||
|
||||
⏱️ Your 5-hour quota has reset
|
||||
📊 Usage: 2%
|
||||
⏰ Next reset: 4h 58m
|
||||
|
||||
Fresh usage available! 🦞
|
||||
```
|
||||
|
||||
**How It Works:**
|
||||
1. **Monitors usage** every 30 minutes (configurable)
|
||||
2. **Detects resets** when usage drops significantly (>10% or <5%)
|
||||
3. **Sends notifications** via Telegram when resets occur
|
||||
4. **Tracks state** in `/tmp/claude-usage-state.json`
|
||||
|
||||
**Customization:**
|
||||
```bash
|
||||
# Change check interval
|
||||
clawdbot cron add --cron "*/15 * * * *" ... # Every 15 minutes
|
||||
clawdbot cron add --cron "0 * * * *" ... # Every hour
|
||||
|
||||
# Custom state file location
|
||||
STATE_FILE=/path/to/state.json ./scripts/monitor-usage.sh
|
||||
```
|
||||
|
||||
### Which Monitoring Method?
|
||||
|
||||
| Feature | Session Reminder | Reset Detection |
|
||||
|---------|-----------------|-----------------|
|
||||
| Accuracy | ✅ Exact minute | ~30min window |
|
||||
| API calls | Minimal | Every check |
|
||||
| Notification timing | Right on reset | Up to 30min delay |
|
||||
| Setup | One command | One command |
|
||||
| Maintenance | Self-scheduling | Cron runs forever |
|
||||
|
||||
**Recommendation:** Use **Session Reminder** for precise, real-time notifications.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**No credentials found:**
|
||||
- Ensure Claude Code CLI is installed and authenticated
|
||||
- Run `claude` once to trigger OAuth flow
|
||||
|
||||
**API request failed:**
|
||||
- Check internet connection
|
||||
- Verify OAuth token hasn't expired
|
||||
- Try `--fresh` to force new request
|
||||
|
||||
**Linux users:**
|
||||
Install `libsecret` for credential storage:
|
||||
```bash
|
||||
# Debian/Ubuntu
|
||||
sudo apt install libsecret-tools
|
||||
|
||||
# Fedora/RHEL
|
||||
sudo dnf install libsecret
|
||||
```
|
||||
268
skills/claude-code-usage/scripts/claude-usage.sh
Executable file
268
skills/claude-code-usage/scripts/claude-usage.sh
Executable file
@@ -0,0 +1,268 @@
|
||||
#!/bin/bash
|
||||
# Claude Code Usage Checker
|
||||
# Queries Anthropic OAuth API for Claude Code rate limits
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CACHE_FILE="${CACHE_FILE:-/tmp/claude-usage-cache}"
|
||||
CACHE_TTL="${CACHE_TTL:-60}" # 1 minute default
|
||||
|
||||
# Parse arguments
|
||||
FORCE_REFRESH=0
|
||||
FORMAT="text"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--fresh|--force)
|
||||
FORCE_REFRESH=1
|
||||
shift
|
||||
;;
|
||||
--json)
|
||||
FORMAT="json"
|
||||
shift
|
||||
;;
|
||||
--cache-ttl)
|
||||
CACHE_TTL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
cat << 'EOF'
|
||||
Usage: claude-usage.sh [OPTIONS]
|
||||
|
||||
Check Claude Code OAuth usage limits (session & weekly).
|
||||
|
||||
Options:
|
||||
--fresh, --force Force refresh (ignore cache)
|
||||
--json Output as JSON
|
||||
--cache-ttl SEC Cache TTL in seconds (default: 60)
|
||||
--help, -h Show this help
|
||||
|
||||
Examples:
|
||||
claude-usage.sh # Use cache if fresh
|
||||
claude-usage.sh --fresh # Force API call
|
||||
claude-usage.sh --json # JSON output
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Function to convert seconds to human readable
|
||||
secs_to_human() {
|
||||
local secs=$1
|
||||
if [ "$secs" -lt 0 ]; then secs=0; fi
|
||||
local days=$((secs / 86400))
|
||||
local hours=$(((secs % 86400) / 3600))
|
||||
local mins=$(((secs % 3600) / 60))
|
||||
|
||||
if [ "$days" -gt 0 ]; then
|
||||
echo "${days}d ${hours}h"
|
||||
elif [ "$hours" -gt 0 ]; then
|
||||
echo "${hours}h ${mins}m"
|
||||
else
|
||||
echo "${mins}m"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check cache (unless force refresh)
|
||||
if [ "$FORCE_REFRESH" -eq 0 ] && [ -f "$CACHE_FILE" ]; then
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
age=$(($(date +%s) - $(stat -f%m "$CACHE_FILE")))
|
||||
else
|
||||
age=$(($(date +%s) - $(stat -c%Y "$CACHE_FILE")))
|
||||
fi
|
||||
|
||||
if [ "$age" -lt "$CACHE_TTL" ]; then
|
||||
cat "$CACHE_FILE"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get OAuth token from keychain (macOS)
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
CREDS=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null || echo "")
|
||||
else
|
||||
# Linux: check common credential stores
|
||||
if command -v secret-tool >/dev/null 2>&1; then
|
||||
CREDS=$(secret-tool lookup application "Claude Code" 2>/dev/null || echo "")
|
||||
else
|
||||
echo "Error: Credential storage not found (macOS keychain or secret-tool required)" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$CREDS" ]; then
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
echo '{"error":"no_credentials","session":null,"weekly":null}'
|
||||
else
|
||||
echo "❌ No Claude Code credentials found"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN=$(echo "$CREDS" | grep -o '"accessToken":"[^"]*"' | sed 's/"accessToken":"//;s/"//')
|
||||
REFRESH_TOKEN=$(echo "$CREDS" | grep -o '"refreshToken":"[^"]*"' | sed 's/"refreshToken":"//;s/"//')
|
||||
EXPIRES_AT=$(echo "$CREDS" | grep -o '"expiresAt":[0-9]*' | sed 's/"expiresAt"://')
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
echo '{"error":"no_token","session":null,"weekly":null}'
|
||||
else
|
||||
echo "❌ Could not extract access token"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if token is expired and refresh if needed
|
||||
if [ -n "$EXPIRES_AT" ]; then
|
||||
NOW_MS=$(($(date +%s) * 1000))
|
||||
if [ "$NOW_MS" -gt "$EXPIRES_AT" ]; then
|
||||
# Token expired - trigger Claude CLI to auto-refresh
|
||||
if command -v claude >/dev/null 2>&1; then
|
||||
# Run a simple query to trigger token refresh
|
||||
echo "2+2" | claude >/dev/null 2>&1 || true
|
||||
|
||||
# Reload credentials from keychain after refresh
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
CREDS=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null || echo "")
|
||||
else
|
||||
if command -v secret-tool >/dev/null 2>&1; then
|
||||
CREDS=$(secret-tool lookup application "Claude Code" 2>/dev/null || echo "")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$CREDS" ]; then
|
||||
TOKEN=$(echo "$CREDS" | grep -o '"accessToken":"[^"]*"' | sed 's/"accessToken":"//;s/"//')
|
||||
fi
|
||||
else
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
echo '{"error":"token_expired","session":null,"weekly":null}'
|
||||
else
|
||||
echo "❌ OAuth token expired. Run 'claude' CLI to refresh."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fetch usage from API
|
||||
RESP=$(curl -s "https://api.anthropic.com/api/oauth/usage" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "anthropic-beta: oauth-2025-04-20" 2>/dev/null)
|
||||
|
||||
if [ -z "$RESP" ]; then
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
echo '{"error":"api_error","session":null,"weekly":null}'
|
||||
else
|
||||
echo "❌ API request failed"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse session (5-hour)
|
||||
SESSION=$(echo "$RESP" | grep -o '"five_hour":{[^}]*}' | grep -o '"utilization":[0-9]*' | sed 's/.*://')
|
||||
SESSION_RESET=$(echo "$RESP" | grep -o '"five_hour":{[^}]*}' | grep -o '"resets_at":"[^"]*"' | sed 's/"resets_at":"//;s/"//')
|
||||
|
||||
# Parse weekly (7-day)
|
||||
WEEKLY=$(echo "$RESP" | grep -o '"seven_day":{[^}]*}' | grep -o '"utilization":[0-9]*' | sed 's/.*://')
|
||||
WEEKLY_RESET=$(echo "$RESP" | grep -o '"seven_day":{[^}]*}' | grep -o '"resets_at":"[^"]*"' | sed 's/"resets_at":"//;s/"//')
|
||||
|
||||
SESSION=${SESSION:-0}
|
||||
WEEKLY=${WEEKLY:-0}
|
||||
|
||||
# Calculate time until reset
|
||||
NOW=$(date +%s)
|
||||
|
||||
if [ -n "$SESSION_RESET" ]; then
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
SESSION_TS=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${SESSION_RESET%Z}" +%s 2>/dev/null || echo 0)
|
||||
else
|
||||
SESSION_TS=$(date -d "${SESSION_RESET}" +%s 2>/dev/null || echo 0)
|
||||
fi
|
||||
SESSION_LEFT=$(secs_to_human $((SESSION_TS - NOW)))
|
||||
else
|
||||
SESSION_LEFT="unknown"
|
||||
fi
|
||||
|
||||
if [ -n "$WEEKLY_RESET" ]; then
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
WEEKLY_TS=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${WEEKLY_RESET%Z}" +%s 2>/dev/null || echo 0)
|
||||
else
|
||||
WEEKLY_TS=$(date -d "${WEEKLY_RESET}" +%s 2>/dev/null || echo 0)
|
||||
fi
|
||||
WEEKLY_LEFT=$(secs_to_human $((WEEKLY_TS - NOW)))
|
||||
else
|
||||
WEEKLY_LEFT="unknown"
|
||||
fi
|
||||
|
||||
# Output format
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
OUTPUT=$(cat <<EOF
|
||||
{
|
||||
"session": {
|
||||
"utilization": $SESSION,
|
||||
"resets_in": "$SESSION_LEFT",
|
||||
"resets_at": "$SESSION_RESET"
|
||||
},
|
||||
"weekly": {
|
||||
"utilization": $WEEKLY,
|
||||
"resets_in": "$WEEKLY_LEFT",
|
||||
"resets_at": "$WEEKLY_RESET"
|
||||
},
|
||||
"cached_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
else
|
||||
# Beautiful text output with emojis
|
||||
SESSION_BAR=""
|
||||
WEEKLY_BAR=""
|
||||
|
||||
# Session progress bar
|
||||
SESSION_FILLED=$((SESSION / 10))
|
||||
SESSION_EMPTY=$((10 - SESSION_FILLED))
|
||||
for ((i=0; i<SESSION_FILLED; i++)); do SESSION_BAR="${SESSION_BAR}█"; done
|
||||
for ((i=0; i<SESSION_EMPTY; i++)); do SESSION_BAR="${SESSION_BAR}░"; done
|
||||
|
||||
# Weekly progress bar
|
||||
WEEKLY_FILLED=$((WEEKLY / 10))
|
||||
WEEKLY_EMPTY=$((10 - WEEKLY_FILLED))
|
||||
for ((i=0; i<WEEKLY_FILLED; i++)); do WEEKLY_BAR="${WEEKLY_BAR}█"; done
|
||||
for ((i=0; i<WEEKLY_EMPTY; i++)); do WEEKLY_BAR="${WEEKLY_BAR}░"; done
|
||||
|
||||
# Determine emoji based on usage level
|
||||
if [ "$SESSION" -gt 80 ]; then
|
||||
SESSION_EMOJI="🔴"
|
||||
elif [ "$SESSION" -gt 50 ]; then
|
||||
SESSION_EMOJI="🟡"
|
||||
else
|
||||
SESSION_EMOJI="🟢"
|
||||
fi
|
||||
|
||||
if [ "$WEEKLY" -gt 80 ]; then
|
||||
WEEKLY_EMOJI="🔴"
|
||||
elif [ "$WEEKLY" -gt 50 ]; then
|
||||
WEEKLY_EMOJI="🟡"
|
||||
else
|
||||
WEEKLY_EMOJI="🟢"
|
||||
fi
|
||||
|
||||
OUTPUT=$(cat <<EOF
|
||||
🦞 Claude Code Usage
|
||||
|
||||
⏱️ Session (5h): $SESSION_EMOJI $SESSION_BAR $SESSION%
|
||||
Resets in: $SESSION_LEFT
|
||||
|
||||
📅 Weekly (7d): $WEEKLY_EMOJI $WEEKLY_BAR $WEEKLY%
|
||||
Resets in: $WEEKLY_LEFT
|
||||
EOF
|
||||
)
|
||||
fi
|
||||
|
||||
# Cache the output
|
||||
echo "$OUTPUT" > "$CACHE_FILE"
|
||||
echo "$OUTPUT"
|
||||
17
skills/claude-code-usage/scripts/monitor-and-notify.sh
Executable file
17
skills/claude-code-usage/scripts/monitor-and-notify.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
# Monitor Claude Code usage and send Telegram notifications on resets
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
OUTPUT=$("$SCRIPT_DIR/monitor-usage.sh" 2>&1)
|
||||
|
||||
# Check if a reset was detected (output contains "Reset notification sent")
|
||||
if echo "$OUTPUT" | grep -q "Reset notification sent"; then
|
||||
# Extract just the notification message (before "✅ Reset notification sent")
|
||||
MESSAGE=$(echo "$OUTPUT" | sed '/✅ Reset notification sent/q' | sed '$ d')
|
||||
|
||||
# Send via Telegram using clawdbot
|
||||
if command -v clawdbot >/dev/null 2>&1; then
|
||||
# Use printf to handle newlines properly
|
||||
printf '%s' "$MESSAGE" | clawdbot message send --telegram --target 5259918241
|
||||
fi
|
||||
fi
|
||||
117
skills/claude-code-usage/scripts/monitor-usage.sh
Executable file
117
skills/claude-code-usage/scripts/monitor-usage.sh
Executable file
@@ -0,0 +1,117 @@
|
||||
#!/bin/bash
|
||||
# Claude Code Usage Monitor
|
||||
# Detects usage resets and sends notifications via Clawdbot
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
STATE_FILE="${STATE_FILE:-/tmp/claude-usage-state.json}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Get current usage (JSON format)
|
||||
CURRENT=$("$SCRIPT_DIR/claude-usage.sh" --json --fresh 2>/dev/null)
|
||||
|
||||
if [ -z "$CURRENT" ]; then
|
||||
echo "❌ Failed to fetch usage" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract current values using better JSON parsing
|
||||
SESSION_NOW=$(echo "$CURRENT" | grep -A3 '"session"' | grep '"utilization"' | grep -o '[0-9]*')
|
||||
WEEKLY_NOW=$(echo "$CURRENT" | grep -A3 '"weekly"' | grep '"utilization"' | grep -o '[0-9]*')
|
||||
SESSION_RESETS=$(echo "$CURRENT" | grep -A3 '"session"' | grep '"resets_in"' | sed 's/.*"resets_in": "//;s/".*//')
|
||||
WEEKLY_RESETS=$(echo "$CURRENT" | grep -A3 '"weekly"' | grep '"resets_in"' | sed 's/.*"resets_in": "//;s/".*//')
|
||||
|
||||
SESSION_NOW=${SESSION_NOW:-0}
|
||||
WEEKLY_NOW=${WEEKLY_NOW:-0}
|
||||
|
||||
# Check if state file exists
|
||||
if [ ! -f "$STATE_FILE" ]; then
|
||||
# First run - save state and exit
|
||||
cat > "$STATE_FILE" <<EOF
|
||||
{
|
||||
"session": $SESSION_NOW,
|
||||
"weekly": $WEEKLY_NOW,
|
||||
"last_check": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
echo "📊 Initial state saved. Monitoring started."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Read previous state
|
||||
SESSION_PREV=$(grep '"session"' "$STATE_FILE" | grep -o '[0-9]*')
|
||||
WEEKLY_PREV=$(grep '"weekly"' "$STATE_FILE" | grep -o '[0-9]*')
|
||||
|
||||
SESSION_PREV=${SESSION_PREV:-0}
|
||||
WEEKLY_PREV=${WEEKLY_PREV:-0}
|
||||
|
||||
# Detect resets (usage went down significantly)
|
||||
SESSION_RESET=0
|
||||
WEEKLY_RESET=0
|
||||
|
||||
# Session reset: if usage dropped by more than 10% AND is now <10%, or dropped by >20%
|
||||
if [ "$SESSION_NOW" -lt "$SESSION_PREV" ]; then
|
||||
if ([ "$SESSION_NOW" -lt 10 ] && [ "$SESSION_PREV" -gt 15 ]) || [ "$SESSION_NOW" -lt $((SESSION_PREV - 20)) ]; then
|
||||
SESSION_RESET=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Weekly reset: if usage dropped by more than 10% AND is now <10%, or dropped by >20%
|
||||
if [ "$WEEKLY_NOW" -lt "$WEEKLY_PREV" ]; then
|
||||
if ([ "$WEEKLY_NOW" -lt 10 ] && [ "$WEEKLY_PREV" -gt 15 ]) || [ "$WEEKLY_NOW" -lt $((WEEKLY_PREV - 20)) ]; then
|
||||
WEEKLY_RESET=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Send notifications if resets detected
|
||||
if [ "$SESSION_RESET" -eq 1 ] || [ "$WEEKLY_RESET" -eq 1 ]; then
|
||||
MESSAGE=""
|
||||
|
||||
if [ "$SESSION_RESET" -eq 1 ]; then
|
||||
MESSAGE="🎉 *Claude Code Session Reset!*\n\n"
|
||||
MESSAGE+="⏱️ Your 5-hour quota has reset\n"
|
||||
MESSAGE+="📊 Usage: *${SESSION_NOW}%*\n"
|
||||
MESSAGE+="⏰ Next reset: ${SESSION_RESETS}\n"
|
||||
fi
|
||||
|
||||
if [ "$WEEKLY_RESET" -eq 1 ]; then
|
||||
if [ -n "$MESSAGE" ]; then
|
||||
MESSAGE+="\n---\n\n"
|
||||
fi
|
||||
MESSAGE+="🎊 *Claude Code Weekly Reset!*\n\n"
|
||||
MESSAGE+="📅 Your 7-day quota has reset\n"
|
||||
MESSAGE+="📊 Usage: *${WEEKLY_NOW}%*\n"
|
||||
MESSAGE+="⏰ Next reset: ${WEEKLY_RESETS}\n"
|
||||
fi
|
||||
|
||||
MESSAGE+="\nFresh usage available! 🦞"
|
||||
|
||||
# Send via clawdbot message tool
|
||||
# Note: This script is typically run by Clawdbot cron, which will capture output
|
||||
# and send it as a notification automatically. For manual testing, print to stdout.
|
||||
echo -e "$MESSAGE"
|
||||
|
||||
echo "✅ Reset notification sent"
|
||||
fi
|
||||
|
||||
# Update state file
|
||||
cat > "$STATE_FILE" <<EOF
|
||||
{
|
||||
"session": $SESSION_NOW,
|
||||
"weekly": $WEEKLY_NOW,
|
||||
"last_check": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Log current status
|
||||
if [ "$SESSION_RESET" -eq 1 ]; then
|
||||
echo "📊 Session: ${SESSION_PREV}% → ${SESSION_NOW}% (RESET)"
|
||||
else
|
||||
echo "📊 Session: ${SESSION_PREV}% → ${SESSION_NOW}%"
|
||||
fi
|
||||
|
||||
if [ "$WEEKLY_RESET" -eq 1 ]; then
|
||||
echo "📊 Weekly: ${WEEKLY_PREV}% → ${WEEKLY_NOW}% (RESET)"
|
||||
else
|
||||
echo "📊 Weekly: ${WEEKLY_PREV}% → ${WEEKLY_NOW}%"
|
||||
fi
|
||||
99
skills/claude-code-usage/scripts/session-reminder.sh
Executable file
99
skills/claude-code-usage/scripts/session-reminder.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
# Claude Code Session Reminder
|
||||
# Notifies when session quota refreshes, then schedules next reminder
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Get current usage (force fresh to get accurate reset time)
|
||||
USAGE=$("$SCRIPT_DIR/claude-usage.sh" --json --fresh 2>/dev/null)
|
||||
|
||||
if [ -z "$USAGE" ]; then
|
||||
echo "❌ Failed to fetch Claude Code usage" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract session info
|
||||
SESSION_UTIL=$(echo "$USAGE" | grep -A3 '"session"' | grep '"utilization"' | grep -o '[0-9]*')
|
||||
SESSION_RESETS=$(echo "$USAGE" | grep -A3 '"session"' | grep '"resets_in"' | sed 's/.*"resets_in": "//;s/".*//')
|
||||
SESSION_RESETS_AT=$(echo "$USAGE" | grep -A3 '"session"' | grep '"resets_at"' | sed 's/.*"resets_at": "//;s/".*//')
|
||||
|
||||
SESSION_UTIL=${SESSION_UTIL:-0}
|
||||
|
||||
# Parse the reset timestamp to get cron schedule
|
||||
if [ -z "$SESSION_RESETS_AT" ] || [ "$SESSION_RESETS_AT" = "null" ]; then
|
||||
echo "❌ Could not determine session reset time" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Convert ISO timestamp to cron format
|
||||
# Example: 2026-01-22T01:22:00.000Z → minute=22, hour=1, day=22, month=1
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# macOS date parsing
|
||||
RESET_TS=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${SESSION_RESETS_AT%.*}" "+%s" 2>/dev/null)
|
||||
else
|
||||
# Linux date parsing
|
||||
RESET_TS=$(date -d "${SESSION_RESETS_AT}" "+%s" 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ -z "$RESET_TS" ] || [ "$RESET_TS" -eq 0 ]; then
|
||||
echo "❌ Failed to parse reset timestamp" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract cron components
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
CRON_MINUTE=$(date -r "$RESET_TS" "+%-M")
|
||||
CRON_HOUR=$(date -r "$RESET_TS" "+%-H")
|
||||
CRON_DAY=$(date -r "$RESET_TS" "+%-d")
|
||||
CRON_MONTH=$(date -r "$RESET_TS" "+%-m")
|
||||
else
|
||||
CRON_MINUTE=$(date -d "@$RESET_TS" "+%-M")
|
||||
CRON_HOUR=$(date -d "@$RESET_TS" "+%-H")
|
||||
CRON_DAY=$(date -d "@$RESET_TS" "+%-d")
|
||||
CRON_MONTH=$(date -d "@$RESET_TS" "+%-m")
|
||||
fi
|
||||
|
||||
# Prepare notification message
|
||||
MESSAGE="🔄 *Claude Code Session Status*
|
||||
|
||||
⏱️ Current usage: *${SESSION_UTIL}%*
|
||||
⏰ Next refresh: ${SESSION_RESETS}
|
||||
|
||||
Your 5-hour quota will reset soon! 🦞"
|
||||
|
||||
# Send notification
|
||||
echo -e "$MESSAGE"
|
||||
|
||||
# Schedule next reminder using clawdbot cron
|
||||
if command -v clawdbot >/dev/null 2>&1; then
|
||||
# Try to remove existing session reminder (ignore errors if none exists)
|
||||
EXISTING=$(clawdbot cron list 2>/dev/null | grep "Claude Code Session Reminder" | head -1 || echo "")
|
||||
if [ -n "$EXISTING" ]; then
|
||||
# Extract ID from the output (format: "id: <uuid>")
|
||||
EXISTING_ID=$(echo "$EXISTING" | grep -o 'id: [a-f0-9-]*' | sed 's/id: //')
|
||||
if [ -n "$EXISTING_ID" ]; then
|
||||
clawdbot cron remove --id "$EXISTING_ID" >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add new one-time cron for next session reset
|
||||
# Note: Using session target to send results back to this session
|
||||
NEXT_TIME=$(date -r "$RESET_TS" "+%Y-%m-%d %H:%M")
|
||||
clawdbot cron add \
|
||||
--cron "$CRON_MINUTE $CRON_HOUR $CRON_DAY $CRON_MONTH *" \
|
||||
--message "Run Claude Code session reminder: $SCRIPT_DIR/session-reminder.sh" \
|
||||
--name "Claude Code Session Reminder" \
|
||||
--description "Next refresh at $NEXT_TIME" \
|
||||
--delete-after-run \
|
||||
--session isolated \
|
||||
--deliver \
|
||||
--channel telegram \
|
||||
>/dev/null 2>&1
|
||||
|
||||
echo ""
|
||||
echo "✅ Next reminder scheduled for: $(date -r "$RESET_TS" "+%b %d at %I:%M %p")"
|
||||
else
|
||||
echo "⚠️ clawdbot not found - cannot schedule next reminder" >&2
|
||||
fi
|
||||
69
skills/claude-code-usage/scripts/setup-monitoring.sh
Executable file
69
skills/claude-code-usage/scripts/setup-monitoring.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
# Setup Claude Code usage monitoring with Clawdbot cron
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MONITOR_SCRIPT="$SCRIPT_DIR/monitor-usage.sh"
|
||||
|
||||
echo "🦞 Claude Code Usage Monitoring Setup"
|
||||
echo ""
|
||||
|
||||
# Check if clawdbot is available
|
||||
if ! command -v clawdbot >/dev/null 2>&1; then
|
||||
echo "❌ clawdbot CLI not found in PATH"
|
||||
echo "Please ensure Clawdbot is installed and accessible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if monitor script exists
|
||||
if [ ! -f "$MONITOR_SCRIPT" ]; then
|
||||
echo "❌ Monitor script not found: $MONITOR_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Default: check every 30 minutes
|
||||
INTERVAL="${1:-30m}"
|
||||
|
||||
echo "📋 Configuration:"
|
||||
echo " Check interval: $INTERVAL"
|
||||
echo " Monitor script: $MONITOR_SCRIPT"
|
||||
echo ""
|
||||
|
||||
# Create cron job via Clawdbot
|
||||
echo "🔧 Creating cron job..."
|
||||
|
||||
# Use clawdbot's cron add command
|
||||
# The job will run the monitor script at the specified interval
|
||||
CRON_TEXT="Monitor Claude Code usage resets every $INTERVAL"
|
||||
|
||||
# Note: This is a placeholder - actual implementation depends on Clawdbot's cron API
|
||||
# For now, we'll output the command that needs to be run
|
||||
|
||||
cat <<EOF
|
||||
|
||||
✅ Setup complete!
|
||||
|
||||
To activate monitoring, run:
|
||||
|
||||
clawdbot cron add \\
|
||||
--schedule "$INTERVAL" \\
|
||||
--command "$MONITOR_SCRIPT" \\
|
||||
--label "Claude Code Usage Monitor"
|
||||
|
||||
Or add via Clawdbot gateway config:
|
||||
|
||||
{
|
||||
"schedule": "$INTERVAL",
|
||||
"command": "$MONITOR_SCRIPT",
|
||||
"label": "Claude Code Usage Monitor"
|
||||
}
|
||||
|
||||
You'll receive notifications when:
|
||||
- 🟢 Your 5-hour session quota resets
|
||||
- 🟢 Your 7-day weekly quota resets
|
||||
|
||||
Test the monitor manually:
|
||||
$MONITOR_SCRIPT
|
||||
|
||||
EOF
|
||||
Reference in New Issue
Block a user