-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdispatch-session-cleaner.sh
More file actions
101 lines (87 loc) · 2.62 KB
/
dispatch-session-cleaner.sh
File metadata and controls
101 lines (87 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env bash
set -euo pipefail
# Dispatch Session Cleaner
# Removes stale local-agent-mode-sessions directories left behind after crashes.
SESSIONS_DIR="${DISPATCH_SESSIONS_DIR:-${HOME}/Library/Application Support/Claude/local-agent-mode-sessions}"
DRY_RUN=false
MAX_AGE_HOURS=24
VERBOSE=false
usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS]
Clean stale Dispatch session directories that persist after crashes.
Options:
-d, --dir DIR Session directory (default: ~/Library/Application Support/Claude/local-agent-mode-sessions)
-n, --dry-run Show what would be removed without deleting
-a, --max-age HRS Max age in hours before considering stale (default: 24)
-v, --verbose Show detailed output
-h, --help Show this help message
EOF
exit 0
}
while [[ $# -gt 0 ]]; do
case "$1" in
-d|--dir) SESSIONS_DIR="$2"; shift 2 ;;
-n|--dry-run) DRY_RUN=true; shift ;;
-a|--max-age) MAX_AGE_HOURS="$2"; shift 2 ;;
-v|--verbose) VERBOSE=true; shift ;;
-h|--help) usage ;;
*) echo "Unknown option: $1" >&2; exit 1 ;;
esac
done
if [[ ! -d "$SESSIONS_DIR" ]]; then
echo "No sessions directory found at: $SESSIONS_DIR"
exit 0
fi
cleaned=0
skipped=0
for session in "$SESSIONS_DIR"/*/; do
[[ -d "$session" ]] || continue
name=$(basename "$session")
stale=false
reason=""
# Check for a PID file indicating the owning process
pid_file="$session/.pid"
if [[ -f "$pid_file" ]]; then
pid=$(cat "$pid_file")
if ! kill -0 "$pid" 2>/dev/null; then
stale=true
reason="process $pid not running"
fi
else
# No PID file — check directory age using modification time
if [[ "$(uname)" == "Darwin" ]]; then
mod_epoch=$(stat -f '%m' "$session")
else
mod_epoch=$(stat -c '%Y' "$session")
fi
now_epoch=$(date +%s)
age_hours=$(( (now_epoch - mod_epoch) / 3600 ))
if (( age_hours >= MAX_AGE_HOURS )); then
stale=true
reason="age ${age_hours}h (threshold ${MAX_AGE_HOURS}h)"
fi
fi
# Check if required subdirectory structure is broken (always stale)
if [[ ! -d "$session/agent" ]] && ! $stale; then
stale=true
reason="missing agent/ subdirectory"
fi
if $stale; then
if $DRY_RUN; then
echo "[dry-run] Would remove: $name ($reason)"
else
rm -rf "$session"
echo "Removed: $name ($reason)"
fi
(( cleaned++ ))
else
$VERBOSE && echo "Kept: $name (still active)"
(( skipped++ ))
fi
done
echo "---"
echo "Cleaned: $cleaned | Skipped: $skipped"
if $DRY_RUN && (( cleaned > 0 )); then
echo "Run without --dry-run to remove stale sessions."
fi