ScuttleBot

1
# Claude Hook Primer
2
3
These hooks are the pre-tool fallback path for a live Claude Code tool loop.
4
Continuous IRC-to-terminal input plus outbound message and tool mirroring are
5
handled by the compiled `cmd/claude-relay` broker, which now sits on the shared
6
`pkg/sessionrelay` connector package.
7
8
If you need to add another runtime later, use
9
[`../ADDING_AGENTS.md`](../ADDING_AGENTS.md) as the shared authoring contract.
10
11
Files in this directory:
12
- `scuttlebot-post.sh`
13
- `scuttlebot-check.sh`
14
15
Related launcher:
16
- `../../../cmd/claude-relay/main.go`
17
- `../scripts/claude-relay.sh`
18
- `../scripts/install-claude-relay.sh`
19
20
Source of truth:
21
- the repo copies in this directory and `../scripts/`
22
- not the installed copies under `~/.claude/` or `~/.local/bin/`
23
24
## What they do
25
26
`scuttlebot-post.sh`
27
- runs after each matching Claude tool call
28
- posts a one-line activity summary into a scuttlebot channel when Claude is not launched through `claude-relay`
29
- stays quiet when `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` so broker-launched sessions do not duplicate activity
30
31
`scuttlebot-check.sh`
32
- runs before the next destructive action
33
- fetches recent channel messages from scuttlebot
34
- ignores bot/status traffic
35
- blocks only when a human explicitly mentions this session nick
36
37
With the broker plus hooks together, you get the full control loop:
38
1. `cmd/claude-relay` posts `online`.
39
2. `cmd/claude-relay` mirrors assistant output and tool activity from the active Claude session log.
40
3. The operator mentions the Claude session nick.
41
4. `cmd/claude-relay` injects that IRC message into the live terminal session immediately.
42
5. `scuttlebot-check.sh` still blocks before the next tool action if needed.
43
44
For immediate startup visibility and continuous IRC input injection, launch Claude
45
through the compiled broker installed as `~/.local/bin/claude-relay`. The repo
46
wrapper `../scripts/claude-relay.sh` is only a development convenience.
47
48
## Default nick format
49
50
If `SCUTTLEBOT_NICK` is unset, the hooks derive:
51
52
```text
53
claude-{basename of cwd}-{session_id[:8]}
54
```
55
56
Session source:
57
- `session_id` from the Claude hook JSON payload
58
- fallback: `$PPID`
59
60
Examples:
61
- `claude-scuttlebot-a1b2c3d4`
62
- `claude-api-e5f6a7b8`
63
64
If you want a fixed nick instead, export `SCUTTLEBOT_NICK` before starting Claude.
65
66
## Required environment
67
68
Required:
69
- `SCUTTLEBOT_URL`
70
- `SCUTTLEBOT_TOKEN`
71
- `SCUTTLEBOT_CHANNEL`
72
73
Optional:
74
- `SCUTTLEBOT_NICK`
75
- `SCUTTLEBOT_CHANNELS`
76
- `SCUTTLEBOT_CHANNEL_STATE_FILE`
77
- `SCUTTLEBOT_TRANSPORT`
78
- `SCUTTLEBOT_IRC_ADDR`
79
- `SCUTTLEBOT_IRC_PASS`
80
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE` — set to `false` to keep agent registration
81
records after the relay disconnects (default: `true`, records are cleaned up)
82
- `SCUTTLEBOT_HOOKS_ENABLED`
83
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE`
84
- `SCUTTLEBOT_POLL_INTERVAL`
85
- `SCUTTLEBOT_PRESENCE_HEARTBEAT`
86
- `SCUTTLEBOT_CONFIG_FILE`
87
- `SCUTTLEBOT_ACTIVITY_VIA_BROKER`
88
89
For automatic reconnection after server restarts or outages, run the
90
`relay-watchdog` sidecar alongside the relay. See `../SKILL.md` for details,
91
or use the `scripts/relay-start.sh` wrapper which handles both processes.
92
93
Example:
94
95
```bash
96
export SCUTTLEBOT_URL=http://localhost:8080
97
export SCUTTLEBOT_TOKEN=$(./run.sh token)
98
export SCUTTLEBOT_CHANNEL=general
99
export SCUTTLEBOT_CHANNELS=general,task-42
100
```
101
102
The hooks also auto-load a shared relay env file if it exists:
103
104
```bash
105
cat > ~/.config/scuttlebot-relay.env <<'EOF'
106
SCUTTLEBOT_URL=http://localhost:8080
107
SCUTTLEBOT_TOKEN=...
108
SCUTTLEBOT_CHANNEL=general
109
SCUTTLEBOT_CHANNELS=general
110
SCUTTLEBOT_TRANSPORT=irc
111
SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667
112
SCUTTLEBOT_HOOKS_ENABLED=1
113
SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
114
SCUTTLEBOT_POLL_INTERVAL=2s
115
SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
116
EOF
117
```
118
119
Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
120
auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
121
you intentionally want a fixed identity.
122
123
Disable the hooks entirely:
124
125
```bash
126
export SCUTTLEBOT_HOOKS_ENABLED=0
127
```
128
129
## Hook config
130
131
Preferred path: run the tracked installer and let it wire the files up for you.
132
133
```bash
134
bash skills/scuttlebot-relay/scripts/install-claude-relay.sh \
135
--url http://localhost:8080 \
136
--token "$(./run.sh token)" \
137
--channel general \
138
--channels general,task-42
139
```
140
141
Manual path:
142
143
```bash
144
mkdir -p ~/.claude/hooks
145
cp skills/scuttlebot-relay/hooks/scuttlebot-post.sh ~/.claude/hooks/
146
cp skills/scuttlebot-relay/hooks/scuttlebot-check.sh ~/.claude/hooks/
147
chmod +x ~/.claude/hooks/scuttlebot-post.sh ~/.claude/hooks/scuttlebot-check.sh
148
```
149
150
Add to `~/.claude/settings.json`:
151
152
```json
153
{
154
"hooks": {
155
"PostToolUse": [
156
{
157
"matcher": "Bash|Read|Edit|Write|Glob|Grep|Agent",
158
"hooks": [{ "type": "command", "command": "~/.claude/hooks/scuttlebot-post.sh" }]
159
}
160
],
161
"PreToolUse": [
162
{
163
"matcher": "Bash|Edit|Write",
164
"hooks": [{ "type": "command", "command": "~/.claude/hooks/scuttlebot-check.sh" }]
165
}
166
]
167
}
168
}
169
```
170
171
Install the compiled broker if you want startup/offline presence plus continuous
172
IRC input injection:
173
174
```bash
175
mkdir -p ~/.local/bin
176
go build -o ~/.local/bin/claude-relay ./cmd/claude-relay
177
chmod +x ~/.local/bin/claude-relay
178
```
179
180
Launch with:
181
182
```bash
183
~/.local/bin/claude-relay
184
```
185
186
## Blocking semantics
187
188
Only addressed instructions block the loop.
189
190
Examples that block:
191
192
```text
193
operator: claude-scuttlebot-a1b2c3d4 stop and inspect the schema first
194
operator: claude-scuttlebot-a1b2c3d4 wrong file
195
```
196
197
Examples that do not block:
198
199
```text
200
operator: someone should inspect the schema
201
claude-otherrepo-e5f6a7b8: read config.go
202
```
203
204
The last-check timestamp is stored in a session-scoped file under `/tmp`, keyed by:
205
- nick
206
- working directory
207
208
That prevents one Claude session from consuming another session's instructions
209
while still allowing the broker to join or part work channels.
210
211
`SCUTTLEBOT_CHANNEL_STATE_FILE` is the broker-written override file that keeps
212
the hooks aligned with live `/join` and `/part` changes.
213
214
## Smoke test
215
216
Use the matching commands from `skills/scuttlebot-relay/install.md`, replacing the
217
nick in the operator message with your Claude session nick.
218
219
## Operational notes
220
221
- These hooks talk to the scuttlebot HTTP API, not raw IRC.
222
- If scuttlebot is down or unreachable, the hooks soft-fail and return quickly.
223
- `SCUTTLEBOT_HOOKS_ENABLED=0` disables both hooks explicitly.
224
- `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` suppresses `scuttlebot-post.sh` when the broker is already mirroring activity.
225
- They should remain in the repo as installable reference files.
226
- Do not bake tokens into the scripts. Use environment variables.
227

Keyboard Shortcuts

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