ScuttleBot

scuttlebot / skills / scuttlebot-relay / hooks / scuttlebot-post.sh
Blame History Raw 124 lines
1
#!/bin/bash
2
# PostToolUse hook — posts what Claude just did to scuttlebot IRC.
3
4
SCUTTLEBOT_CONFIG_FILE="${SCUTTLEBOT_CONFIG_FILE:-$HOME/.config/scuttlebot-relay.env}"
5
if [ -f "$SCUTTLEBOT_CONFIG_FILE" ]; then
6
set -a
7
. "$SCUTTLEBOT_CONFIG_FILE"
8
set +a
9
fi
10
if [ -n "${SCUTTLEBOT_CHANNEL_STATE_FILE:-}" ] && [ -f "$SCUTTLEBOT_CHANNEL_STATE_FILE" ]; then
11
set -a
12
. "$SCUTTLEBOT_CHANNEL_STATE_FILE"
13
set +a
14
fi
15
16
SCUTTLEBOT_URL="${SCUTTLEBOT_URL:-http://localhost:8080}"
17
SCUTTLEBOT_TOKEN="${SCUTTLEBOT_TOKEN}"
18
SCUTTLEBOT_CHANNEL="${SCUTTLEBOT_CHANNEL:-general}"
19
SCUTTLEBOT_HOOKS_ENABLED="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
20
SCUTTLEBOT_ACTIVITY_VIA_BROKER="${SCUTTLEBOT_ACTIVITY_VIA_BROKER:-0}"
21
22
normalize_channel() {
23
local channel="$1"
24
channel="${channel//[$' \t\r\n']/}"
25
channel="${channel#\#}"
26
printf '%s' "$channel"
27
}
28
29
relay_channels() {
30
local raw="${SCUTTLEBOT_CHANNELS:-$SCUTTLEBOT_CHANNEL}"
31
local IFS=','
32
local item channel seen=""
33
read -r -a items <<< "$raw"
34
for item in "${items[@]}"; do
35
channel=$(normalize_channel "$item")
36
[ -n "$channel" ] || continue
37
case ",$seen," in
38
*,"$channel",*) ;;
39
*)
40
seen="${seen:+$seen,}$channel"
41
printf '%s\n' "$channel"
42
;;
43
esac
44
done
45
}
46
47
post_message() {
48
local text="$1"
49
local payload
50
payload="{\"text\": $(printf '%s' "$text" | jq -Rs .), \"nick\": \"$SCUTTLEBOT_NICK\"}"
51
for channel in $(relay_channels); do
52
curl -sf -X POST "$SCUTTLEBOT_URL/v1/channels/$channel/messages" \
53
--connect-timeout 1 \
54
--max-time 2 \
55
-H "Authorization: Bearer $SCUTTLEBOT_TOKEN" \
56
-H "Content-Type: application/json" \
57
-d "$payload" \
58
> /dev/null || true
59
done
60
}
61
62
input=$(cat)
63
64
tool=$(echo "$input" | jq -r '.tool_name // empty')
65
cwd=$(echo "$input" | jq -r '.cwd // empty')
66
67
sanitize() {
68
printf '%s' "$1" | tr -cs '[:alnum:]_-' '-'
69
}
70
71
if [ -z "$cwd" ]; then
72
cwd=$(pwd)
73
fi
74
base_name=$(sanitize "$(basename "$cwd")")
75
session_id=$(echo "$input" | jq -r '.session_id // empty' | head -c 8)
76
session_suffix="${session_id:-$PPID}"
77
default_nick="claude-${base_name}-${session_suffix}"
78
SCUTTLEBOT_NICK="${SCUTTLEBOT_NICK:-$default_nick}"
79
80
[ "$SCUTTLEBOT_HOOKS_ENABLED" = "0" ] && exit 0
81
[ "$SCUTTLEBOT_HOOKS_ENABLED" = "false" ] && exit 0
82
[ "$SCUTTLEBOT_ACTIVITY_VIA_BROKER" = "1" ] && exit 0
83
[ "$SCUTTLEBOT_ACTIVITY_VIA_BROKER" = "true" ] && exit 0
84
[ -z "$SCUTTLEBOT_TOKEN" ] && exit 0
85
86
case "$tool" in
87
Bash)
88
cmd=$(echo "$input" | jq -r '.tool_input.command // empty' | head -c 120)
89
msg="› $cmd"
90
;;
91
Read)
92
file=$(echo "$input" | jq -r '.tool_input.file_path // empty' | sed "s|$cwd/||")
93
msg="read $file"
94
;;
95
Edit)
96
file=$(echo "$input" | jq -r '.tool_input.file_path // empty' | sed "s|$cwd/||")
97
msg="edit $file"
98
;;
99
Write)
100
file=$(echo "$input" | jq -r '.tool_input.file_path // empty' | sed "s|$cwd/||")
101
msg="write $file"
102
;;
103
Glob)
104
pattern=$(echo "$input" | jq -r '.tool_input.pattern // empty')
105
msg="glob $pattern"
106
;;
107
Grep)
108
pattern=$(echo "$input" | jq -r '.tool_input.pattern // empty')
109
msg="grep \"$pattern\""
110
;;
111
Agent)
112
desc=$(echo "$input" | jq -r '.tool_input.description // empty' | head -c 80)
113
msg="spawn agent: $desc"
114
;;
115
*)
116
msg="$tool"
117
;;
118
esac
119
120
[ -z "$msg" ] && exit 0
121
122
post_message "$msg"
123
exit 0
124

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button