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:
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