ScuttleBot

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

Keyboard Shortcuts

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