ScuttleBot

Default relay installers to IRC auto-registration

lmata 2026-04-01 14:06 trunk
Commit b8ce8438e143d17f42db832ebbc11bd55c2fd9ebc58292b295d82ec42c8d30cd
--- skills/gemini-relay/FLEET.md
+++ skills/gemini-relay/FLEET.md
@@ -113,10 +113,11 @@
113113
The installer is intentionally narrow. It:
114114
- copies the tracked hook scripts into `~/.gemini/hooks/`
115115
- builds and installs `gemini-relay` into `~/.local/bin/`
116116
- merges required hook entries into `~/.gemini/settings.json`
117117
- writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
118
+- defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
118119
- keeps one backup copy as `*.bak` before overwriting an existing installed file
119120
120121
It does not:
121122
- replace the real `gemini` binary in `PATH`
122123
- force a fixed nick across sessions
@@ -123,19 +124,23 @@
123124
- require IRC to be up at install time
124125
125126
Useful shared env knobs:
126127
- `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
127128
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
128
-- `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration
129
+- `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
129130
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
130131
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Gemini session when it appears busy
131132
- `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
132133
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
133134
- `SCUTTLEBOT_AFTER_AGENT_MAX_POSTS=6` caps how many IRC messages one final Gemini reply may emit
134135
- `SCUTTLEBOT_AFTER_AGENT_CHUNK_WIDTH=360` controls the maximum width of each mirrored reply chunk
135136
- `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
136137
138
+Installer auth knobs:
139
+- default or `--auto-register`: scrub `SCUTTLEBOT_IRC_PASS` from the shared env file and let the broker auto-register ephemeral session nicks
140
+- `--irc-pass <passphrase>`: persist a fixed NickServ password in the shared env file
141
+
137142
## Operator workflow
138143
139144
1. Watch the configured channel in scuttlebot.
140145
2. Wait for a new `gemini-{repo}-{session}` online post.
141146
3. Mention that nick when you need to steer the session.
142147
--- skills/gemini-relay/FLEET.md
+++ skills/gemini-relay/FLEET.md
@@ -113,10 +113,11 @@
113 The installer is intentionally narrow. It:
114 - copies the tracked hook scripts into `~/.gemini/hooks/`
115 - builds and installs `gemini-relay` into `~/.local/bin/`
116 - merges required hook entries into `~/.gemini/settings.json`
117 - writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
 
118 - keeps one backup copy as `*.bak` before overwriting an existing installed file
119
120 It does not:
121 - replace the real `gemini` binary in `PATH`
122 - force a fixed nick across sessions
@@ -123,19 +124,23 @@
123 - require IRC to be up at install time
124
125 Useful shared env knobs:
126 - `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
127 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
128 - `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration
129 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
130 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Gemini session when it appears busy
131 - `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
132 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
133 - `SCUTTLEBOT_AFTER_AGENT_MAX_POSTS=6` caps how many IRC messages one final Gemini reply may emit
134 - `SCUTTLEBOT_AFTER_AGENT_CHUNK_WIDTH=360` controls the maximum width of each mirrored reply chunk
135 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
136
 
 
 
 
137 ## Operator workflow
138
139 1. Watch the configured channel in scuttlebot.
140 2. Wait for a new `gemini-{repo}-{session}` online post.
141 3. Mention that nick when you need to steer the session.
142
--- skills/gemini-relay/FLEET.md
+++ skills/gemini-relay/FLEET.md
@@ -113,10 +113,11 @@
113 The installer is intentionally narrow. It:
114 - copies the tracked hook scripts into `~/.gemini/hooks/`
115 - builds and installs `gemini-relay` into `~/.local/bin/`
116 - merges required hook entries into `~/.gemini/settings.json`
117 - writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
118 - defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
119 - keeps one backup copy as `*.bak` before overwriting an existing installed file
120
121 It does not:
122 - replace the real `gemini` binary in `PATH`
123 - force a fixed nick across sessions
@@ -123,19 +124,23 @@
124 - require IRC to be up at install time
125
126 Useful shared env knobs:
127 - `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
128 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
129 - `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
130 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
131 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Gemini session when it appears busy
132 - `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
133 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
134 - `SCUTTLEBOT_AFTER_AGENT_MAX_POSTS=6` caps how many IRC messages one final Gemini reply may emit
135 - `SCUTTLEBOT_AFTER_AGENT_CHUNK_WIDTH=360` controls the maximum width of each mirrored reply chunk
136 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
137
138 Installer auth knobs:
139 - default or `--auto-register`: scrub `SCUTTLEBOT_IRC_PASS` from the shared env file and let the broker auto-register ephemeral session nicks
140 - `--irc-pass <passphrase>`: persist a fixed NickServ password in the shared env file
141
142 ## Operator workflow
143
144 1. Watch the configured channel in scuttlebot.
145 2. Wait for a new `gemini-{repo}-{session}` online post.
146 3. Mention that nick when you need to steer the session.
147
--- skills/gemini-relay/hooks/README.md
+++ skills/gemini-relay/hooks/README.md
@@ -124,10 +124,14 @@
124124
SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
125125
SCUTTLEBOT_POLL_INTERVAL=2s
126126
SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
127127
EOF2
128128
```
129
+
130
+Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
131
+auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
132
+you intentionally want a fixed identity.
129133
130134
Disable the hooks entirely:
131135
132136
```bash
133137
export SCUTTLEBOT_HOOKS_ENABLED=0
134138
--- skills/gemini-relay/hooks/README.md
+++ skills/gemini-relay/hooks/README.md
@@ -124,10 +124,14 @@
124 SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
125 SCUTTLEBOT_POLL_INTERVAL=2s
126 SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
127 EOF2
128 ```
 
 
 
 
129
130 Disable the hooks entirely:
131
132 ```bash
133 export SCUTTLEBOT_HOOKS_ENABLED=0
134
--- skills/gemini-relay/hooks/README.md
+++ skills/gemini-relay/hooks/README.md
@@ -124,10 +124,14 @@
124 SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
125 SCUTTLEBOT_POLL_INTERVAL=2s
126 SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
127 EOF2
128 ```
129
130 Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
131 auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
132 you intentionally want a fixed identity.
133
134 Disable the hooks entirely:
135
136 ```bash
137 export SCUTTLEBOT_HOOKS_ENABLED=0
138
--- skills/gemini-relay/install.md
+++ skills/gemini-relay/install.md
@@ -72,10 +72,15 @@
7272
~/.local/bin/gemini-relay
7373
```
7474
7575
The relay will generate a stable, unique nick for the session: `gemini-{repo}-{session_id[:8]}`.
7676
77
+Installer auth modes:
78
+- default: omit `SCUTTLEBOT_IRC_PASS` and let the broker auto-register the session nick
79
+- `--irc-pass <passphrase>`: pin a fixed NickServ password in the shared env file
80
+- `--auto-register`: remove any stale `SCUTTLEBOT_IRC_PASS` entry from the shared env file
81
+
7782
## Behavior
7883
7984
- **Ambient Chat:** Unaddressed chat in the channel does not interrupt your work.
8085
- **Operator Instruction:** Mention your session's nick to interrupt and provide guidance.
8186
- **Presence:** `SCUTTLEBOT_TRANSPORT=http` uses silent presence heartbeats; `SCUTTLEBOT_TRANSPORT=irc` uses a real IRC socket for native presence.
@@ -85,11 +90,11 @@
8590
## Configuration
8691
8792
Useful shared env knobs in `~/.config/scuttlebot-relay.env`:
8893
- `SCUTTLEBOT_TRANSPORT=http|irc` — selects the connector backend
8994
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` — sets the real IRC address when transport is `irc`
90
-- `SCUTTLEBOT_IRC_PASS=...` — uses a fixed NickServ password instead of auto-registration
95
+- `SCUTTLEBOT_IRC_PASS=...` — uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
9196
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` — keeps auto-registered session nicks after clean exit
9297
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` — interrupts the live Gemini session when it appears busy
9398
- `SCUTTLEBOT_POLL_INTERVAL=2s` — controls how often the broker checks for new addressed IRC messages
9499
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` — controls HTTP presence touches; set `0` to disable
95100
- `SCUTTLEBOT_AFTER_AGENT_MAX_POSTS=6` — caps how many IRC messages one final Gemini reply may emit
96101
--- skills/gemini-relay/install.md
+++ skills/gemini-relay/install.md
@@ -72,10 +72,15 @@
72 ~/.local/bin/gemini-relay
73 ```
74
75 The relay will generate a stable, unique nick for the session: `gemini-{repo}-{session_id[:8]}`.
76
 
 
 
 
 
77 ## Behavior
78
79 - **Ambient Chat:** Unaddressed chat in the channel does not interrupt your work.
80 - **Operator Instruction:** Mention your session's nick to interrupt and provide guidance.
81 - **Presence:** `SCUTTLEBOT_TRANSPORT=http` uses silent presence heartbeats; `SCUTTLEBOT_TRANSPORT=irc` uses a real IRC socket for native presence.
@@ -85,11 +90,11 @@
85 ## Configuration
86
87 Useful shared env knobs in `~/.config/scuttlebot-relay.env`:
88 - `SCUTTLEBOT_TRANSPORT=http|irc` — selects the connector backend
89 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` — sets the real IRC address when transport is `irc`
90 - `SCUTTLEBOT_IRC_PASS=...` — uses a fixed NickServ password instead of auto-registration
91 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` — keeps auto-registered session nicks after clean exit
92 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` — interrupts the live Gemini session when it appears busy
93 - `SCUTTLEBOT_POLL_INTERVAL=2s` — controls how often the broker checks for new addressed IRC messages
94 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` — controls HTTP presence touches; set `0` to disable
95 - `SCUTTLEBOT_AFTER_AGENT_MAX_POSTS=6` — caps how many IRC messages one final Gemini reply may emit
96
--- skills/gemini-relay/install.md
+++ skills/gemini-relay/install.md
@@ -72,10 +72,15 @@
72 ~/.local/bin/gemini-relay
73 ```
74
75 The relay will generate a stable, unique nick for the session: `gemini-{repo}-{session_id[:8]}`.
76
77 Installer auth modes:
78 - default: omit `SCUTTLEBOT_IRC_PASS` and let the broker auto-register the session nick
79 - `--irc-pass <passphrase>`: pin a fixed NickServ password in the shared env file
80 - `--auto-register`: remove any stale `SCUTTLEBOT_IRC_PASS` entry from the shared env file
81
82 ## Behavior
83
84 - **Ambient Chat:** Unaddressed chat in the channel does not interrupt your work.
85 - **Operator Instruction:** Mention your session's nick to interrupt and provide guidance.
86 - **Presence:** `SCUTTLEBOT_TRANSPORT=http` uses silent presence heartbeats; `SCUTTLEBOT_TRANSPORT=irc` uses a real IRC socket for native presence.
@@ -85,11 +90,11 @@
90 ## Configuration
91
92 Useful shared env knobs in `~/.config/scuttlebot-relay.env`:
93 - `SCUTTLEBOT_TRANSPORT=http|irc` — selects the connector backend
94 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` — sets the real IRC address when transport is `irc`
95 - `SCUTTLEBOT_IRC_PASS=...` — uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
96 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` — keeps auto-registered session nicks after clean exit
97 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` — interrupts the live Gemini session when it appears busy
98 - `SCUTTLEBOT_POLL_INTERVAL=2s` — controls how often the broker checks for new addressed IRC messages
99 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` — controls HTTP presence touches; set `0` to disable
100 - `SCUTTLEBOT_AFTER_AGENT_MAX_POSTS=6` — caps how many IRC messages one final Gemini reply may emit
101
--- skills/gemini-relay/scripts/install-gemini-relay.sh
+++ skills/gemini-relay/scripts/install-gemini-relay.sh
@@ -12,10 +12,12 @@
1212
--url URL Set SCUTTLEBOT_URL in the shared env file.
1313
--token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
1414
--channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
1515
--transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: http.
1616
--irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
17
+ --irc-pass PASS Write SCUTTLEBOT_IRC_PASS for fixed-identity IRC mode.
18
+ --auto-register Remove SCUTTLEBOT_IRC_PASS so IRC mode auto-registers session nicks. Default.
1719
--enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
1820
--disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
1921
--config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
2022
--hooks-dir PATH Gemini hooks install dir. Default: ~/.gemini/hooks
2123
--settings-json PATH Gemini settings JSON. Default: ~/.gemini/settings.json
@@ -54,11 +56,18 @@
5456
SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
5557
SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
5658
SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
5759
SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-http}"
5860
SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
59
-SCUTTLEBOT_IRC_PASS_VALUE="${SCUTTLEBOT_IRC_PASS:-}"
61
+if [ -n "${SCUTTLEBOT_IRC_PASS:-}" ]; then
62
+ SCUTTLEBOT_IRC_PASS_MODE="fixed"
63
+ SCUTTLEBOT_IRC_PASS_VALUE="$SCUTTLEBOT_IRC_PASS"
64
+else
65
+ SCUTTLEBOT_IRC_PASS_MODE="auto"
66
+ SCUTTLEBOT_IRC_PASS_VALUE=""
67
+fi
68
+SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE="${SCUTTLEBOT_IRC_DELETE_ON_CLOSE:-1}"
6069
SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
6170
SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
6271
SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
6372
SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
6473
@@ -86,10 +95,20 @@
8695
shift 2
8796
;;
8897
--irc-addr)
8998
SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
9099
shift 2
100
+ ;;
101
+ --irc-pass)
102
+ SCUTTLEBOT_IRC_PASS_MODE="fixed"
103
+ SCUTTLEBOT_IRC_PASS_VALUE="${2:?missing value for --irc-pass}"
104
+ shift 2
105
+ ;;
106
+ --auto-register)
107
+ SCUTTLEBOT_IRC_PASS_MODE="auto"
108
+ SCUTTLEBOT_IRC_PASS_VALUE=""
109
+ shift
91110
;;
92111
--enabled)
93112
SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
94113
shift
95114
;;
@@ -162,10 +181,20 @@
162181
END {
163182
if (!done) {
164183
print key "=" value
165184
}
166185
}
186
+ ' "$file" > "${file}.tmp"
187
+ mv "${file}.tmp" "$file"
188
+}
189
+
190
+remove_env_var() {
191
+ local file="$1"
192
+ local key="$2"
193
+ awk -v key="$key" '
194
+ $0 ~ "^(export[[:space:]]+)?" key "=" { next }
195
+ { print }
167196
' "$file" > "${file}.tmp"
168197
mv "${file}.tmp" "$file"
169198
}
170199
171200
need_cmd jq
@@ -269,13 +298,16 @@
269298
if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
270299
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
271300
fi
272301
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
273302
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
274
-if [ -n "$SCUTTLEBOT_IRC_PASS_VALUE" ]; then
303
+if [ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ]; then
275304
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
305
+else
306
+ remove_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS
276307
fi
308
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_DELETE_ON_CLOSE "$SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE"
277309
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
278310
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
279311
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
280312
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
281313
@@ -282,13 +314,14 @@
282314
printf 'Installed Gemini relay files:\n'
283315
printf ' hooks: %s\n' "$HOOKS_DIR"
284316
printf ' settings: %s\n' "$SETTINGS_JSON"
285317
printf ' launcher: %s\n' "$LAUNCHER_DST"
286318
printf ' env: %s\n' "$CONFIG_FILE"
319
+printf ' irc auth: %s\n' "$([ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ] && printf 'fixed-pass override' || printf 'auto-register')"
287320
printf '\n'
288321
printf 'Next steps:\n'
289322
printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
290323
printf ' 2. Watch IRC for: gemini-{repo}-{session}\n'
291324
printf ' 3. Mention that nick to interrupt before the next action\n'
292325
printf '\n'
293326
printf 'Disable without uninstalling:\n'
294327
printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
295328
--- skills/gemini-relay/scripts/install-gemini-relay.sh
+++ skills/gemini-relay/scripts/install-gemini-relay.sh
@@ -12,10 +12,12 @@
12 --url URL Set SCUTTLEBOT_URL in the shared env file.
13 --token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
14 --channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
15 --transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: http.
16 --irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
 
 
17 --enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
18 --disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
19 --config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
20 --hooks-dir PATH Gemini hooks install dir. Default: ~/.gemini/hooks
21 --settings-json PATH Gemini settings JSON. Default: ~/.gemini/settings.json
@@ -54,11 +56,18 @@
54 SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
55 SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
56 SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
57 SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-http}"
58 SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
59 SCUTTLEBOT_IRC_PASS_VALUE="${SCUTTLEBOT_IRC_PASS:-}"
 
 
 
 
 
 
 
60 SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
61 SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
62 SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
63 SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
64
@@ -86,10 +95,20 @@
86 shift 2
87 ;;
88 --irc-addr)
89 SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
90 shift 2
 
 
 
 
 
 
 
 
 
 
91 ;;
92 --enabled)
93 SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
94 shift
95 ;;
@@ -162,10 +181,20 @@
162 END {
163 if (!done) {
164 print key "=" value
165 }
166 }
 
 
 
 
 
 
 
 
 
 
167 ' "$file" > "${file}.tmp"
168 mv "${file}.tmp" "$file"
169 }
170
171 need_cmd jq
@@ -269,13 +298,16 @@
269 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
270 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
271 fi
272 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
273 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
274 if [ -n "$SCUTTLEBOT_IRC_PASS_VALUE" ]; then
275 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
 
 
276 fi
 
277 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
278 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
279 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
280 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
281
@@ -282,13 +314,14 @@
282 printf 'Installed Gemini relay files:\n'
283 printf ' hooks: %s\n' "$HOOKS_DIR"
284 printf ' settings: %s\n' "$SETTINGS_JSON"
285 printf ' launcher: %s\n' "$LAUNCHER_DST"
286 printf ' env: %s\n' "$CONFIG_FILE"
 
287 printf '\n'
288 printf 'Next steps:\n'
289 printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
290 printf ' 2. Watch IRC for: gemini-{repo}-{session}\n'
291 printf ' 3. Mention that nick to interrupt before the next action\n'
292 printf '\n'
293 printf 'Disable without uninstalling:\n'
294 printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
295
--- skills/gemini-relay/scripts/install-gemini-relay.sh
+++ skills/gemini-relay/scripts/install-gemini-relay.sh
@@ -12,10 +12,12 @@
12 --url URL Set SCUTTLEBOT_URL in the shared env file.
13 --token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
14 --channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
15 --transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: http.
16 --irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
17 --irc-pass PASS Write SCUTTLEBOT_IRC_PASS for fixed-identity IRC mode.
18 --auto-register Remove SCUTTLEBOT_IRC_PASS so IRC mode auto-registers session nicks. Default.
19 --enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
20 --disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
21 --config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
22 --hooks-dir PATH Gemini hooks install dir. Default: ~/.gemini/hooks
23 --settings-json PATH Gemini settings JSON. Default: ~/.gemini/settings.json
@@ -54,11 +56,18 @@
56 SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
57 SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
58 SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
59 SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-http}"
60 SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
61 if [ -n "${SCUTTLEBOT_IRC_PASS:-}" ]; then
62 SCUTTLEBOT_IRC_PASS_MODE="fixed"
63 SCUTTLEBOT_IRC_PASS_VALUE="$SCUTTLEBOT_IRC_PASS"
64 else
65 SCUTTLEBOT_IRC_PASS_MODE="auto"
66 SCUTTLEBOT_IRC_PASS_VALUE=""
67 fi
68 SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE="${SCUTTLEBOT_IRC_DELETE_ON_CLOSE:-1}"
69 SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
70 SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
71 SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
72 SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
73
@@ -86,10 +95,20 @@
95 shift 2
96 ;;
97 --irc-addr)
98 SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
99 shift 2
100 ;;
101 --irc-pass)
102 SCUTTLEBOT_IRC_PASS_MODE="fixed"
103 SCUTTLEBOT_IRC_PASS_VALUE="${2:?missing value for --irc-pass}"
104 shift 2
105 ;;
106 --auto-register)
107 SCUTTLEBOT_IRC_PASS_MODE="auto"
108 SCUTTLEBOT_IRC_PASS_VALUE=""
109 shift
110 ;;
111 --enabled)
112 SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
113 shift
114 ;;
@@ -162,10 +181,20 @@
181 END {
182 if (!done) {
183 print key "=" value
184 }
185 }
186 ' "$file" > "${file}.tmp"
187 mv "${file}.tmp" "$file"
188 }
189
190 remove_env_var() {
191 local file="$1"
192 local key="$2"
193 awk -v key="$key" '
194 $0 ~ "^(export[[:space:]]+)?" key "=" { next }
195 { print }
196 ' "$file" > "${file}.tmp"
197 mv "${file}.tmp" "$file"
198 }
199
200 need_cmd jq
@@ -269,13 +298,16 @@
298 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
299 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
300 fi
301 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
302 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
303 if [ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ]; then
304 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
305 else
306 remove_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS
307 fi
308 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_DELETE_ON_CLOSE "$SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE"
309 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
310 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
311 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
312 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
313
@@ -282,13 +314,14 @@
314 printf 'Installed Gemini relay files:\n'
315 printf ' hooks: %s\n' "$HOOKS_DIR"
316 printf ' settings: %s\n' "$SETTINGS_JSON"
317 printf ' launcher: %s\n' "$LAUNCHER_DST"
318 printf ' env: %s\n' "$CONFIG_FILE"
319 printf ' irc auth: %s\n' "$([ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ] && printf 'fixed-pass override' || printf 'auto-register')"
320 printf '\n'
321 printf 'Next steps:\n'
322 printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
323 printf ' 2. Watch IRC for: gemini-{repo}-{session}\n'
324 printf ' 3. Mention that nick to interrupt before the next action\n'
325 printf '\n'
326 printf 'Disable without uninstalling:\n'
327 printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
328
--- skills/openai-relay/FLEET.md
+++ skills/openai-relay/FLEET.md
@@ -114,10 +114,11 @@
114114
- copies the tracked hook scripts into `~/.codex/hooks/`
115115
- builds and installs `codex-relay` into `~/.local/bin/`
116116
- merges required hook entries into `~/.codex/hooks.json`
117117
- ensures `features.codex_hooks = true` in `~/.codex/config.toml`
118118
- writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
119
+- defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
119120
- keeps one backup copy as `*.bak` before overwriting an existing installed file
120121
121122
It does not:
122123
- replace the real `codex` binary in `PATH`
123124
- force a fixed nick across sessions
@@ -124,17 +125,21 @@
124125
- require IRC to be up at install time
125126
126127
Useful shared env knobs:
127128
- `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
128129
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
129
-- `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration
130
+- `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
130131
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
131132
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Codex session only when Codex appears busy; idle sessions are injected directly and auto-submitted
132133
- `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
133134
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
134135
- `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
135136
137
+Installer auth knobs:
138
+- default or `--auto-register`: scrub `SCUTTLEBOT_IRC_PASS` from the shared env file and let the broker auto-register ephemeral session nicks
139
+- `--irc-pass <passphrase>`: persist a fixed NickServ password in the shared env file
140
+
136141
## Operator workflow
137142
138143
1. Watch the configured channel in scuttlebot.
139144
2. Wait for a new `codex-{repo}-{session}` online post.
140145
3. Mention that nick when you need to steer the session.
141146
--- skills/openai-relay/FLEET.md
+++ skills/openai-relay/FLEET.md
@@ -114,10 +114,11 @@
114 - copies the tracked hook scripts into `~/.codex/hooks/`
115 - builds and installs `codex-relay` into `~/.local/bin/`
116 - merges required hook entries into `~/.codex/hooks.json`
117 - ensures `features.codex_hooks = true` in `~/.codex/config.toml`
118 - writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
 
119 - keeps one backup copy as `*.bak` before overwriting an existing installed file
120
121 It does not:
122 - replace the real `codex` binary in `PATH`
123 - force a fixed nick across sessions
@@ -124,17 +125,21 @@
124 - require IRC to be up at install time
125
126 Useful shared env knobs:
127 - `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
128 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
129 - `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration
130 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
131 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Codex session only when Codex appears busy; idle sessions are injected directly and auto-submitted
132 - `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
133 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
134 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
135
 
 
 
 
136 ## Operator workflow
137
138 1. Watch the configured channel in scuttlebot.
139 2. Wait for a new `codex-{repo}-{session}` online post.
140 3. Mention that nick when you need to steer the session.
141
--- skills/openai-relay/FLEET.md
+++ skills/openai-relay/FLEET.md
@@ -114,10 +114,11 @@
114 - copies the tracked hook scripts into `~/.codex/hooks/`
115 - builds and installs `codex-relay` into `~/.local/bin/`
116 - merges required hook entries into `~/.codex/hooks.json`
117 - ensures `features.codex_hooks = true` in `~/.codex/config.toml`
118 - writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
119 - defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
120 - keeps one backup copy as `*.bak` before overwriting an existing installed file
121
122 It does not:
123 - replace the real `codex` binary in `PATH`
124 - force a fixed nick across sessions
@@ -124,17 +125,21 @@
125 - require IRC to be up at install time
126
127 Useful shared env knobs:
128 - `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
129 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
130 - `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
131 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
132 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Codex session only when Codex appears busy; idle sessions are injected directly and auto-submitted
133 - `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
134 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
135 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
136
137 Installer auth knobs:
138 - default or `--auto-register`: scrub `SCUTTLEBOT_IRC_PASS` from the shared env file and let the broker auto-register ephemeral session nicks
139 - `--irc-pass <passphrase>`: persist a fixed NickServ password in the shared env file
140
141 ## Operator workflow
142
143 1. Watch the configured channel in scuttlebot.
144 2. Wait for a new `codex-{repo}-{session}` online post.
145 3. Mention that nick when you need to steer the session.
146
--- skills/openai-relay/hooks/README.md
+++ skills/openai-relay/hooks/README.md
@@ -109,10 +109,14 @@
109109
SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
110110
SCUTTLEBOT_POLL_INTERVAL=2s
111111
SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
112112
EOF
113113
```
114
+
115
+Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
116
+auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
117
+you intentionally want a fixed identity.
114118
115119
Disable the hooks entirely:
116120
117121
```bash
118122
export SCUTTLEBOT_HOOKS_ENABLED=0
119123
--- skills/openai-relay/hooks/README.md
+++ skills/openai-relay/hooks/README.md
@@ -109,10 +109,14 @@
109 SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
110 SCUTTLEBOT_POLL_INTERVAL=2s
111 SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
112 EOF
113 ```
 
 
 
 
114
115 Disable the hooks entirely:
116
117 ```bash
118 export SCUTTLEBOT_HOOKS_ENABLED=0
119
--- skills/openai-relay/hooks/README.md
+++ skills/openai-relay/hooks/README.md
@@ -109,10 +109,14 @@
109 SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
110 SCUTTLEBOT_POLL_INTERVAL=2s
111 SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
112 EOF
113 ```
114
115 Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
116 auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
117 you intentionally want a fixed identity.
118
119 Disable the hooks entirely:
120
121 ```bash
122 export SCUTTLEBOT_HOOKS_ENABLED=0
123
--- skills/openai-relay/install.md
+++ skills/openai-relay/install.md
@@ -61,10 +61,11 @@
6161
- copies the tracked hook scripts into `~/.codex/hooks/`
6262
- builds and installs `codex-relay` into `~/.local/bin/`
6363
- merges the required entries into `~/.codex/hooks.json`
6464
- enables `features.codex_hooks = true` in `~/.codex/config.toml`
6565
- writes or updates `~/.config/scuttlebot-relay.env`
66
+- defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
6667
6768
Runtime behavior:
6869
- `cmd/codex-relay` keeps Codex on a real PTY
6970
- it posts `online` immediately on launch
7071
- it mirrors assistant messages and tool activity from the active session log
@@ -91,10 +92,16 @@
9192
9293
Common knobs:
9394
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667`
9495
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s`
9596
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=1`
97
+- `SCUTTLEBOT_IRC_PASS` only when you intentionally want a fixed NickServ identity instead of auto-registration
98
+
99
+Installer auth modes:
100
+- default: omit `SCUTTLEBOT_IRC_PASS` and let the broker auto-register the session nick
101
+- `--irc-pass <passphrase>`: pin a fixed NickServ password in the shared env file
102
+- `--auto-register`: remove any stale `SCUTTLEBOT_IRC_PASS` entry from the shared env file
96103
97104
Examples:
98105
99106
```bash
100107
# HTTP bridge path
@@ -200,11 +207,11 @@
200207
Optional broker env:
201208
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=0` disables the automatic busy-session interrupt before injected IRC instructions
202209
- `SCUTTLEBOT_POLL_INTERVAL=1s` tunes how often the broker polls for new addressed IRC messages
203210
- `SCUTTLEBOT_TRANSPORT=irc` switches from the HTTP bridge path to a real IRC socket
204211
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` points the real IRC transport at Ergo
205
-- `SCUTTLEBOT_IRC_PASS=<passphrase>` skips auto-registration and uses a fixed NickServ password
212
+- `SCUTTLEBOT_IRC_PASS=<passphrase>` skips auto-registration and uses a fixed NickServ password; leave it unset for the default broker convention
206213
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=0` disables HTTP presence heartbeats
207214
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks in the registry after clean exit
208215
209216
If you want `codex` itself to always use the wrapper, prefer a shell alias:
210217
211218
--- skills/openai-relay/install.md
+++ skills/openai-relay/install.md
@@ -61,10 +61,11 @@
61 - copies the tracked hook scripts into `~/.codex/hooks/`
62 - builds and installs `codex-relay` into `~/.local/bin/`
63 - merges the required entries into `~/.codex/hooks.json`
64 - enables `features.codex_hooks = true` in `~/.codex/config.toml`
65 - writes or updates `~/.config/scuttlebot-relay.env`
 
66
67 Runtime behavior:
68 - `cmd/codex-relay` keeps Codex on a real PTY
69 - it posts `online` immediately on launch
70 - it mirrors assistant messages and tool activity from the active session log
@@ -91,10 +92,16 @@
91
92 Common knobs:
93 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667`
94 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s`
95 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=1`
 
 
 
 
 
 
96
97 Examples:
98
99 ```bash
100 # HTTP bridge path
@@ -200,11 +207,11 @@
200 Optional broker env:
201 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=0` disables the automatic busy-session interrupt before injected IRC instructions
202 - `SCUTTLEBOT_POLL_INTERVAL=1s` tunes how often the broker polls for new addressed IRC messages
203 - `SCUTTLEBOT_TRANSPORT=irc` switches from the HTTP bridge path to a real IRC socket
204 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` points the real IRC transport at Ergo
205 - `SCUTTLEBOT_IRC_PASS=<passphrase>` skips auto-registration and uses a fixed NickServ password
206 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=0` disables HTTP presence heartbeats
207 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks in the registry after clean exit
208
209 If you want `codex` itself to always use the wrapper, prefer a shell alias:
210
211
--- skills/openai-relay/install.md
+++ skills/openai-relay/install.md
@@ -61,10 +61,11 @@
61 - copies the tracked hook scripts into `~/.codex/hooks/`
62 - builds and installs `codex-relay` into `~/.local/bin/`
63 - merges the required entries into `~/.codex/hooks.json`
64 - enables `features.codex_hooks = true` in `~/.codex/config.toml`
65 - writes or updates `~/.config/scuttlebot-relay.env`
66 - defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
67
68 Runtime behavior:
69 - `cmd/codex-relay` keeps Codex on a real PTY
70 - it posts `online` immediately on launch
71 - it mirrors assistant messages and tool activity from the active session log
@@ -91,10 +92,16 @@
92
93 Common knobs:
94 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667`
95 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s`
96 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=1`
97 - `SCUTTLEBOT_IRC_PASS` only when you intentionally want a fixed NickServ identity instead of auto-registration
98
99 Installer auth modes:
100 - default: omit `SCUTTLEBOT_IRC_PASS` and let the broker auto-register the session nick
101 - `--irc-pass <passphrase>`: pin a fixed NickServ password in the shared env file
102 - `--auto-register`: remove any stale `SCUTTLEBOT_IRC_PASS` entry from the shared env file
103
104 Examples:
105
106 ```bash
107 # HTTP bridge path
@@ -200,11 +207,11 @@
207 Optional broker env:
208 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=0` disables the automatic busy-session interrupt before injected IRC instructions
209 - `SCUTTLEBOT_POLL_INTERVAL=1s` tunes how often the broker polls for new addressed IRC messages
210 - `SCUTTLEBOT_TRANSPORT=irc` switches from the HTTP bridge path to a real IRC socket
211 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` points the real IRC transport at Ergo
212 - `SCUTTLEBOT_IRC_PASS=<passphrase>` skips auto-registration and uses a fixed NickServ password; leave it unset for the default broker convention
213 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=0` disables HTTP presence heartbeats
214 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks in the registry after clean exit
215
216 If you want `codex` itself to always use the wrapper, prefer a shell alias:
217
218
--- skills/openai-relay/scripts/install-codex-relay.sh
+++ skills/openai-relay/scripts/install-codex-relay.sh
@@ -12,10 +12,12 @@
1212
--url URL Set SCUTTLEBOT_URL in the shared env file.
1313
--token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
1414
--channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
1515
--transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: http.
1616
--irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
17
+ --irc-pass PASS Write SCUTTLEBOT_IRC_PASS for fixed-identity IRC mode.
18
+ --auto-register Remove SCUTTLEBOT_IRC_PASS so IRC mode auto-registers session nicks. Default.
1719
--enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
1820
--disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
1921
--config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
2022
--hooks-dir PATH Codex hooks install dir. Default: ~/.codex/hooks
2123
--hooks-json PATH Codex hooks config JSON. Default: ~/.codex/hooks.json
@@ -54,11 +56,18 @@
5456
SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
5557
SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
5658
SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
5759
SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-http}"
5860
SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
59
-SCUTTLEBOT_IRC_PASS_VALUE="${SCUTTLEBOT_IRC_PASS:-}"
61
+if [ -n "${SCUTTLEBOT_IRC_PASS:-}" ]; then
62
+ SCUTTLEBOT_IRC_PASS_MODE="fixed"
63
+ SCUTTLEBOT_IRC_PASS_VALUE="$SCUTTLEBOT_IRC_PASS"
64
+else
65
+ SCUTTLEBOT_IRC_PASS_MODE="auto"
66
+ SCUTTLEBOT_IRC_PASS_VALUE=""
67
+fi
68
+SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE="${SCUTTLEBOT_IRC_DELETE_ON_CLOSE:-1}"
6069
SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
6170
SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
6271
SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
6372
SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
6473
@@ -87,10 +96,20 @@
8796
shift 2
8897
;;
8998
--irc-addr)
9099
SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
91100
shift 2
101
+ ;;
102
+ --irc-pass)
103
+ SCUTTLEBOT_IRC_PASS_MODE="fixed"
104
+ SCUTTLEBOT_IRC_PASS_VALUE="${2:?missing value for --irc-pass}"
105
+ shift 2
106
+ ;;
107
+ --auto-register)
108
+ SCUTTLEBOT_IRC_PASS_MODE="auto"
109
+ SCUTTLEBOT_IRC_PASS_VALUE=""
110
+ shift
92111
;;
93112
--enabled)
94113
SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
95114
shift
96115
;;
@@ -167,10 +186,20 @@
167186
END {
168187
if (!done) {
169188
print key "=" value
170189
}
171190
}
191
+ ' "$file" > "${file}.tmp"
192
+ mv "${file}.tmp" "$file"
193
+}
194
+
195
+remove_env_var() {
196
+ local file="$1"
197
+ local key="$2"
198
+ awk -v key="$key" '
199
+ $0 ~ "^(export[[:space:]]+)?" key "=" { next }
200
+ { print }
172201
' "$file" > "${file}.tmp"
173202
mv "${file}.tmp" "$file"
174203
}
175204
176205
ensure_codex_hooks_feature() {
@@ -322,13 +351,16 @@
322351
if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
323352
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
324353
fi
325354
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
326355
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
327
-if [ -n "$SCUTTLEBOT_IRC_PASS_VALUE" ]; then
356
+if [ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ]; then
328357
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
358
+else
359
+ remove_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS
329360
fi
361
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_DELETE_ON_CLOSE "$SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE"
330362
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
331363
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
332364
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
333365
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
334366
@@ -336,13 +368,14 @@
336368
printf ' hooks: %s\n' "$HOOKS_DIR"
337369
printf ' hooks.json: %s\n' "$HOOKS_JSON"
338370
printf ' config: %s\n' "$CODEX_CONFIG"
339371
printf ' broker: %s\n' "$LAUNCHER_DST"
340372
printf ' env: %s\n' "$CONFIG_FILE"
373
+printf ' irc auth: %s\n' "$([ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ] && printf 'fixed-pass override' || printf 'auto-register')"
341374
printf '\n'
342375
printf 'Next steps:\n'
343376
printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
344377
printf ' 2. Watch IRC for: codex-{repo}-{session}\n'
345378
printf ' 3. Mention that nick to interrupt before the next action\n'
346379
printf '\n'
347380
printf 'Disable without uninstalling:\n'
348381
printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
349382
--- skills/openai-relay/scripts/install-codex-relay.sh
+++ skills/openai-relay/scripts/install-codex-relay.sh
@@ -12,10 +12,12 @@
12 --url URL Set SCUTTLEBOT_URL in the shared env file.
13 --token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
14 --channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
15 --transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: http.
16 --irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
 
 
17 --enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
18 --disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
19 --config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
20 --hooks-dir PATH Codex hooks install dir. Default: ~/.codex/hooks
21 --hooks-json PATH Codex hooks config JSON. Default: ~/.codex/hooks.json
@@ -54,11 +56,18 @@
54 SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
55 SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
56 SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
57 SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-http}"
58 SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
59 SCUTTLEBOT_IRC_PASS_VALUE="${SCUTTLEBOT_IRC_PASS:-}"
 
 
 
 
 
 
 
60 SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
61 SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
62 SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
63 SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
64
@@ -87,10 +96,20 @@
87 shift 2
88 ;;
89 --irc-addr)
90 SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
91 shift 2
 
 
 
 
 
 
 
 
 
 
92 ;;
93 --enabled)
94 SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
95 shift
96 ;;
@@ -167,10 +186,20 @@
167 END {
168 if (!done) {
169 print key "=" value
170 }
171 }
 
 
 
 
 
 
 
 
 
 
172 ' "$file" > "${file}.tmp"
173 mv "${file}.tmp" "$file"
174 }
175
176 ensure_codex_hooks_feature() {
@@ -322,13 +351,16 @@
322 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
323 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
324 fi
325 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
326 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
327 if [ -n "$SCUTTLEBOT_IRC_PASS_VALUE" ]; then
328 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
 
 
329 fi
 
330 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
331 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
332 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
333 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
334
@@ -336,13 +368,14 @@
336 printf ' hooks: %s\n' "$HOOKS_DIR"
337 printf ' hooks.json: %s\n' "$HOOKS_JSON"
338 printf ' config: %s\n' "$CODEX_CONFIG"
339 printf ' broker: %s\n' "$LAUNCHER_DST"
340 printf ' env: %s\n' "$CONFIG_FILE"
 
341 printf '\n'
342 printf 'Next steps:\n'
343 printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
344 printf ' 2. Watch IRC for: codex-{repo}-{session}\n'
345 printf ' 3. Mention that nick to interrupt before the next action\n'
346 printf '\n'
347 printf 'Disable without uninstalling:\n'
348 printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
349
--- skills/openai-relay/scripts/install-codex-relay.sh
+++ skills/openai-relay/scripts/install-codex-relay.sh
@@ -12,10 +12,12 @@
12 --url URL Set SCUTTLEBOT_URL in the shared env file.
13 --token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
14 --channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
15 --transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: http.
16 --irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
17 --irc-pass PASS Write SCUTTLEBOT_IRC_PASS for fixed-identity IRC mode.
18 --auto-register Remove SCUTTLEBOT_IRC_PASS so IRC mode auto-registers session nicks. Default.
19 --enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
20 --disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
21 --config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
22 --hooks-dir PATH Codex hooks install dir. Default: ~/.codex/hooks
23 --hooks-json PATH Codex hooks config JSON. Default: ~/.codex/hooks.json
@@ -54,11 +56,18 @@
56 SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
57 SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
58 SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
59 SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-http}"
60 SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
61 if [ -n "${SCUTTLEBOT_IRC_PASS:-}" ]; then
62 SCUTTLEBOT_IRC_PASS_MODE="fixed"
63 SCUTTLEBOT_IRC_PASS_VALUE="$SCUTTLEBOT_IRC_PASS"
64 else
65 SCUTTLEBOT_IRC_PASS_MODE="auto"
66 SCUTTLEBOT_IRC_PASS_VALUE=""
67 fi
68 SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE="${SCUTTLEBOT_IRC_DELETE_ON_CLOSE:-1}"
69 SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
70 SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
71 SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
72 SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
73
@@ -87,10 +96,20 @@
96 shift 2
97 ;;
98 --irc-addr)
99 SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
100 shift 2
101 ;;
102 --irc-pass)
103 SCUTTLEBOT_IRC_PASS_MODE="fixed"
104 SCUTTLEBOT_IRC_PASS_VALUE="${2:?missing value for --irc-pass}"
105 shift 2
106 ;;
107 --auto-register)
108 SCUTTLEBOT_IRC_PASS_MODE="auto"
109 SCUTTLEBOT_IRC_PASS_VALUE=""
110 shift
111 ;;
112 --enabled)
113 SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
114 shift
115 ;;
@@ -167,10 +186,20 @@
186 END {
187 if (!done) {
188 print key "=" value
189 }
190 }
191 ' "$file" > "${file}.tmp"
192 mv "${file}.tmp" "$file"
193 }
194
195 remove_env_var() {
196 local file="$1"
197 local key="$2"
198 awk -v key="$key" '
199 $0 ~ "^(export[[:space:]]+)?" key "=" { next }
200 { print }
201 ' "$file" > "${file}.tmp"
202 mv "${file}.tmp" "$file"
203 }
204
205 ensure_codex_hooks_feature() {
@@ -322,13 +351,16 @@
351 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
352 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
353 fi
354 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
355 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
356 if [ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ]; then
357 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
358 else
359 remove_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS
360 fi
361 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_DELETE_ON_CLOSE "$SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE"
362 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
363 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
364 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
365 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
366
@@ -336,13 +368,14 @@
368 printf ' hooks: %s\n' "$HOOKS_DIR"
369 printf ' hooks.json: %s\n' "$HOOKS_JSON"
370 printf ' config: %s\n' "$CODEX_CONFIG"
371 printf ' broker: %s\n' "$LAUNCHER_DST"
372 printf ' env: %s\n' "$CONFIG_FILE"
373 printf ' irc auth: %s\n' "$([ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ] && printf 'fixed-pass override' || printf 'auto-register')"
374 printf '\n'
375 printf 'Next steps:\n'
376 printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
377 printf ' 2. Watch IRC for: codex-{repo}-{session}\n'
378 printf ' 3. Mention that nick to interrupt before the next action\n'
379 printf '\n'
380 printf 'Disable without uninstalling:\n'
381 printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
382
--- skills/scuttlebot-relay/ADDING_AGENTS.md
+++ skills/scuttlebot-relay/ADDING_AGENTS.md
@@ -82,10 +82,11 @@
8282
## Canonical terminal-broker conventions
8383
8484
Every terminal broker should follow these conventions:
8585
- one stable nick per live session: `{runtime}-{basename}-{session}`
8686
- one shared env contract using `SCUTTLEBOT_*`
87
+- installer default is auto-registration: leave `SCUTTLEBOT_IRC_PASS` unset and remove stale fixed-pass values unless the operator explicitly requests a fixed identity
8788
- one broker process owning `online` / `offline`
8889
- one broker process owning continuous addressed operator input injection
8990
- one broker process owning outbound activity and assistant-message mirroring when the runtime exposes a reliable event/session stream
9091
- hooks used for pre-action fallback and for runtime-specific gaps such as post-tool summaries or final reply hooks
9192
- support both `SCUTTLEBOT_TRANSPORT=http` and `SCUTTLEBOT_TRANSPORT=irc` behind the same broker contract
@@ -109,10 +110,12 @@
109110
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE`
110111
- `SCUTTLEBOT_POLL_INTERVAL`
111112
- `SCUTTLEBOT_PRESENCE_HEARTBEAT`
112113
113114
Do not hardcode tokens into repo scripts.
115
+For terminal-session brokers, treat `SCUTTLEBOT_IRC_PASS` as an explicit
116
+fixed-identity override, not a default.
114117
115118
## Nicking rules
116119
117120
Use a stable, human-addressable session nick.
118121
119122
--- skills/scuttlebot-relay/ADDING_AGENTS.md
+++ skills/scuttlebot-relay/ADDING_AGENTS.md
@@ -82,10 +82,11 @@
82 ## Canonical terminal-broker conventions
83
84 Every terminal broker should follow these conventions:
85 - one stable nick per live session: `{runtime}-{basename}-{session}`
86 - one shared env contract using `SCUTTLEBOT_*`
 
87 - one broker process owning `online` / `offline`
88 - one broker process owning continuous addressed operator input injection
89 - one broker process owning outbound activity and assistant-message mirroring when the runtime exposes a reliable event/session stream
90 - hooks used for pre-action fallback and for runtime-specific gaps such as post-tool summaries or final reply hooks
91 - support both `SCUTTLEBOT_TRANSPORT=http` and `SCUTTLEBOT_TRANSPORT=irc` behind the same broker contract
@@ -109,10 +110,12 @@
109 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE`
110 - `SCUTTLEBOT_POLL_INTERVAL`
111 - `SCUTTLEBOT_PRESENCE_HEARTBEAT`
112
113 Do not hardcode tokens into repo scripts.
 
 
114
115 ## Nicking rules
116
117 Use a stable, human-addressable session nick.
118
119
--- skills/scuttlebot-relay/ADDING_AGENTS.md
+++ skills/scuttlebot-relay/ADDING_AGENTS.md
@@ -82,10 +82,11 @@
82 ## Canonical terminal-broker conventions
83
84 Every terminal broker should follow these conventions:
85 - one stable nick per live session: `{runtime}-{basename}-{session}`
86 - one shared env contract using `SCUTTLEBOT_*`
87 - installer default is auto-registration: leave `SCUTTLEBOT_IRC_PASS` unset and remove stale fixed-pass values unless the operator explicitly requests a fixed identity
88 - one broker process owning `online` / `offline`
89 - one broker process owning continuous addressed operator input injection
90 - one broker process owning outbound activity and assistant-message mirroring when the runtime exposes a reliable event/session stream
91 - hooks used for pre-action fallback and for runtime-specific gaps such as post-tool summaries or final reply hooks
92 - support both `SCUTTLEBOT_TRANSPORT=http` and `SCUTTLEBOT_TRANSPORT=irc` behind the same broker contract
@@ -109,10 +110,12 @@
110 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE`
111 - `SCUTTLEBOT_POLL_INTERVAL`
112 - `SCUTTLEBOT_PRESENCE_HEARTBEAT`
113
114 Do not hardcode tokens into repo scripts.
115 For terminal-session brokers, treat `SCUTTLEBOT_IRC_PASS` as an explicit
116 fixed-identity override, not a default.
117
118 ## Nicking rules
119
120 Use a stable, human-addressable session nick.
121
122
--- skills/scuttlebot-relay/FLEET.md
+++ skills/scuttlebot-relay/FLEET.md
@@ -91,10 +91,11 @@
9191
The installer is intentionally narrow. It:
9292
- copies the tracked hook scripts into `~/.claude/hooks/`
9393
- builds and installs `claude-relay` into `~/.local/bin/`
9494
- merges required hook entries into `~/.claude/settings.json`
9595
- writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
96
+- defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
9697
- keeps one backup copy as `*.bak` before overwriting an existing installed file
9798
9899
It does not:
99100
- replace the real `claude` binary in `PATH`
100101
- force a fixed nick across sessions
@@ -101,17 +102,21 @@
101102
- require IRC to be up at install time
102103
103104
Useful shared env knobs:
104105
- `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
105106
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
106
-- `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration
107
+- `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
107108
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
108109
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Claude session when it appears busy
109110
- `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
110111
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
111112
- `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
112113
114
+Installer auth knobs:
115
+- default or `--auto-register`: scrub `SCUTTLEBOT_IRC_PASS` from the shared env file and let the broker auto-register ephemeral session nicks
116
+- `--irc-pass <passphrase>`: persist a fixed NickServ password in the shared env file
117
+
113118
## Operator workflow
114119
115120
1. Watch the configured channel in scuttlebot.
116121
2. Wait for a new `claude-{repo}-{session}` online post.
117122
3. Mention that nick when you need to steer the session.
118123
--- skills/scuttlebot-relay/FLEET.md
+++ skills/scuttlebot-relay/FLEET.md
@@ -91,10 +91,11 @@
91 The installer is intentionally narrow. It:
92 - copies the tracked hook scripts into `~/.claude/hooks/`
93 - builds and installs `claude-relay` into `~/.local/bin/`
94 - merges required hook entries into `~/.claude/settings.json`
95 - writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
 
96 - keeps one backup copy as `*.bak` before overwriting an existing installed file
97
98 It does not:
99 - replace the real `claude` binary in `PATH`
100 - force a fixed nick across sessions
@@ -101,17 +102,21 @@
101 - require IRC to be up at install time
102
103 Useful shared env knobs:
104 - `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
105 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
106 - `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration
107 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
108 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Claude session when it appears busy
109 - `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
110 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
111 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
112
 
 
 
 
113 ## Operator workflow
114
115 1. Watch the configured channel in scuttlebot.
116 2. Wait for a new `claude-{repo}-{session}` online post.
117 3. Mention that nick when you need to steer the session.
118
--- skills/scuttlebot-relay/FLEET.md
+++ skills/scuttlebot-relay/FLEET.md
@@ -91,10 +91,11 @@
91 The installer is intentionally narrow. It:
92 - copies the tracked hook scripts into `~/.claude/hooks/`
93 - builds and installs `claude-relay` into `~/.local/bin/`
94 - merges required hook entries into `~/.claude/settings.json`
95 - writes `SCUTTLEBOT_*` settings into `~/.config/scuttlebot-relay.env`
96 - defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
97 - keeps one backup copy as `*.bak` before overwriting an existing installed file
98
99 It does not:
100 - replace the real `claude` binary in `PATH`
101 - force a fixed nick across sessions
@@ -101,17 +102,21 @@
102 - require IRC to be up at install time
103
104 Useful shared env knobs:
105 - `SCUTTLEBOT_TRANSPORT=http|irc` selects the connector backend
106 - `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` sets the real IRC address when transport is `irc`
107 - `SCUTTLEBOT_IRC_PASS=...` uses a fixed NickServ password instead of auto-registration; leave it unset for the default broker convention
108 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks after clean exit
109 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1` interrupts the live Claude session when it appears busy
110 - `SCUTTLEBOT_POLL_INTERVAL=2s` controls how often the broker checks for new addressed IRC messages
111 - `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` controls HTTP presence touches; set `0` to disable
112 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` tells `scuttlebot-post.sh` to stay quiet so broker-launched sessions do not duplicate activity posts
113
114 Installer auth knobs:
115 - default or `--auto-register`: scrub `SCUTTLEBOT_IRC_PASS` from the shared env file and let the broker auto-register ephemeral session nicks
116 - `--irc-pass <passphrase>`: persist a fixed NickServ password in the shared env file
117
118 ## Operator workflow
119
120 1. Watch the configured channel in scuttlebot.
121 2. Wait for a new `claude-{repo}-{session}` online post.
122 3. Mention that nick when you need to steer the session.
123
--- skills/scuttlebot-relay/hooks/README.md
+++ skills/scuttlebot-relay/hooks/README.md
@@ -1,28 +1,52 @@
11
# Claude Hook Primer
22
3
-These hooks are the operator-control path for a live Claude Code tool loop.
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.
47
58
If you need to add another runtime later, use
69
[`../ADDING_AGENTS.md`](../ADDING_AGENTS.md) as the shared authoring contract.
710
811
Files in this directory:
912
- `scuttlebot-post.sh`
1013
- `scuttlebot-check.sh`
1114
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
+
1224
## What they do
1325
1426
`scuttlebot-post.sh`
1527
- runs after each matching Claude tool call
16
-- posts a one-line activity summary to the shared scuttlebot channel
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
1730
1831
`scuttlebot-check.sh`
1932
- runs before the next destructive action
2033
- fetches recent channel messages from scuttlebot
2134
- ignores bot/status traffic
2235
- blocks only when a human explicitly mentions this session nick
2336
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
+
2448
## Default nick format
2549
2650
If `SCUTTLEBOT_NICK` is unset, the hooks derive:
2751
2852
```text
@@ -46,12 +70,20 @@
4670
- `SCUTTLEBOT_TOKEN`
4771
- `SCUTTLEBOT_CHANNEL`
4872
4973
Optional:
5074
- `SCUTTLEBOT_NICK`
75
+- `SCUTTLEBOT_TRANSPORT`
76
+- `SCUTTLEBOT_IRC_ADDR`
77
+- `SCUTTLEBOT_IRC_PASS`
78
+- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE`
5179
- `SCUTTLEBOT_HOOKS_ENABLED`
80
+- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE`
81
+- `SCUTTLEBOT_POLL_INTERVAL`
82
+- `SCUTTLEBOT_PRESENCE_HEARTBEAT`
5283
- `SCUTTLEBOT_CONFIG_FILE`
84
+- `SCUTTLEBOT_ACTIVITY_VIA_BROKER`
5385
5486
Example:
5587
5688
```bash
5789
export SCUTTLEBOT_URL=http://localhost:8080
@@ -64,21 +96,41 @@
6496
```bash
6597
cat > ~/.config/scuttlebot-relay.env <<'EOF'
6698
SCUTTLEBOT_URL=http://localhost:8080
6799
SCUTTLEBOT_TOKEN=...
68100
SCUTTLEBOT_CHANNEL=general
101
+SCUTTLEBOT_TRANSPORT=irc
102
+SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667
69103
SCUTTLEBOT_HOOKS_ENABLED=1
104
+SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
105
+SCUTTLEBOT_POLL_INTERVAL=2s
106
+SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
70107
EOF
71108
```
109
+
110
+Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
111
+auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
112
+you intentionally want a fixed identity.
72113
73114
Disable the hooks entirely:
74115
75116
```bash
76117
export SCUTTLEBOT_HOOKS_ENABLED=0
77118
```
78119
79
-## Claude install
120
+## Hook config
121
+
122
+Preferred path: run the tracked installer and let it wire the files up for you.
123
+
124
+```bash
125
+bash skills/scuttlebot-relay/scripts/install-claude-relay.sh \
126
+ --url http://localhost:8080 \
127
+ --token "$(./run.sh token)" \
128
+ --channel general
129
+```
130
+
131
+Manual path:
80132
81133
```bash
82134
mkdir -p ~/.claude/hooks
83135
cp skills/scuttlebot-relay/hooks/scuttlebot-post.sh ~/.claude/hooks/
84136
cp skills/scuttlebot-relay/hooks/scuttlebot-check.sh ~/.claude/hooks/
@@ -103,10 +155,25 @@
103155
}
104156
]
105157
}
106158
}
107159
```
160
+
161
+Install the compiled broker if you want startup/offline presence plus continuous
162
+IRC input injection:
163
+
164
+```bash
165
+mkdir -p ~/.local/bin
166
+go build -o ~/.local/bin/claude-relay ./cmd/claude-relay
167
+chmod +x ~/.local/bin/claude-relay
168
+```
169
+
170
+Launch with:
171
+
172
+```bash
173
+~/.local/bin/claude-relay
174
+```
108175
109176
## Blocking semantics
110177
111178
Only addressed instructions block the loop.
112179
@@ -139,7 +206,8 @@
139206
## Operational notes
140207
141208
- These hooks talk to the scuttlebot HTTP API, not raw IRC.
142209
- If scuttlebot is down or unreachable, the hooks soft-fail and return quickly.
143210
- `SCUTTLEBOT_HOOKS_ENABLED=0` disables both hooks explicitly.
211
+- `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` suppresses `scuttlebot-post.sh` when the broker is already mirroring activity.
144212
- They should remain in the repo as installable reference files.
145213
- Do not bake tokens into the scripts. Use environment variables.
146214
--- skills/scuttlebot-relay/hooks/README.md
+++ skills/scuttlebot-relay/hooks/README.md
@@ -1,28 +1,52 @@
1 # Claude Hook Primer
2
3 These hooks are the operator-control path for a live Claude Code tool loop.
 
 
 
4
5 If you need to add another runtime later, use
6 [`../ADDING_AGENTS.md`](../ADDING_AGENTS.md) as the shared authoring contract.
7
8 Files in this directory:
9 - `scuttlebot-post.sh`
10 - `scuttlebot-check.sh`
11
 
 
 
 
 
 
 
 
 
12 ## What they do
13
14 `scuttlebot-post.sh`
15 - runs after each matching Claude tool call
16 - posts a one-line activity summary to the shared scuttlebot channel
 
17
18 `scuttlebot-check.sh`
19 - runs before the next destructive action
20 - fetches recent channel messages from scuttlebot
21 - ignores bot/status traffic
22 - blocks only when a human explicitly mentions this session nick
23
 
 
 
 
 
 
 
 
 
 
 
24 ## Default nick format
25
26 If `SCUTTLEBOT_NICK` is unset, the hooks derive:
27
28 ```text
@@ -46,12 +70,20 @@
46 - `SCUTTLEBOT_TOKEN`
47 - `SCUTTLEBOT_CHANNEL`
48
49 Optional:
50 - `SCUTTLEBOT_NICK`
 
 
 
 
51 - `SCUTTLEBOT_HOOKS_ENABLED`
 
 
 
52 - `SCUTTLEBOT_CONFIG_FILE`
 
53
54 Example:
55
56 ```bash
57 export SCUTTLEBOT_URL=http://localhost:8080
@@ -64,21 +96,41 @@
64 ```bash
65 cat > ~/.config/scuttlebot-relay.env <<'EOF'
66 SCUTTLEBOT_URL=http://localhost:8080
67 SCUTTLEBOT_TOKEN=...
68 SCUTTLEBOT_CHANNEL=general
 
 
69 SCUTTLEBOT_HOOKS_ENABLED=1
 
 
 
70 EOF
71 ```
 
 
 
 
72
73 Disable the hooks entirely:
74
75 ```bash
76 export SCUTTLEBOT_HOOKS_ENABLED=0
77 ```
78
79 ## Claude install
 
 
 
 
 
 
 
 
 
 
 
80
81 ```bash
82 mkdir -p ~/.claude/hooks
83 cp skills/scuttlebot-relay/hooks/scuttlebot-post.sh ~/.claude/hooks/
84 cp skills/scuttlebot-relay/hooks/scuttlebot-check.sh ~/.claude/hooks/
@@ -103,10 +155,25 @@
103 }
104 ]
105 }
106 }
107 ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
109 ## Blocking semantics
110
111 Only addressed instructions block the loop.
112
@@ -139,7 +206,8 @@
139 ## Operational notes
140
141 - These hooks talk to the scuttlebot HTTP API, not raw IRC.
142 - If scuttlebot is down or unreachable, the hooks soft-fail and return quickly.
143 - `SCUTTLEBOT_HOOKS_ENABLED=0` disables both hooks explicitly.
 
144 - They should remain in the repo as installable reference files.
145 - Do not bake tokens into the scripts. Use environment variables.
146
--- skills/scuttlebot-relay/hooks/README.md
+++ skills/scuttlebot-relay/hooks/README.md
@@ -1,28 +1,52 @@
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
@@ -46,12 +70,20 @@
70 - `SCUTTLEBOT_TOKEN`
71 - `SCUTTLEBOT_CHANNEL`
72
73 Optional:
74 - `SCUTTLEBOT_NICK`
75 - `SCUTTLEBOT_TRANSPORT`
76 - `SCUTTLEBOT_IRC_ADDR`
77 - `SCUTTLEBOT_IRC_PASS`
78 - `SCUTTLEBOT_IRC_DELETE_ON_CLOSE`
79 - `SCUTTLEBOT_HOOKS_ENABLED`
80 - `SCUTTLEBOT_INTERRUPT_ON_MESSAGE`
81 - `SCUTTLEBOT_POLL_INTERVAL`
82 - `SCUTTLEBOT_PRESENCE_HEARTBEAT`
83 - `SCUTTLEBOT_CONFIG_FILE`
84 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER`
85
86 Example:
87
88 ```bash
89 export SCUTTLEBOT_URL=http://localhost:8080
@@ -64,21 +96,41 @@
96 ```bash
97 cat > ~/.config/scuttlebot-relay.env <<'EOF'
98 SCUTTLEBOT_URL=http://localhost:8080
99 SCUTTLEBOT_TOKEN=...
100 SCUTTLEBOT_CHANNEL=general
101 SCUTTLEBOT_TRANSPORT=irc
102 SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667
103 SCUTTLEBOT_HOOKS_ENABLED=1
104 SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
105 SCUTTLEBOT_POLL_INTERVAL=2s
106 SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
107 EOF
108 ```
109
110 Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
111 auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
112 you intentionally want a fixed identity.
113
114 Disable the hooks entirely:
115
116 ```bash
117 export SCUTTLEBOT_HOOKS_ENABLED=0
118 ```
119
120 ## Hook config
121
122 Preferred path: run the tracked installer and let it wire the files up for you.
123
124 ```bash
125 bash skills/scuttlebot-relay/scripts/install-claude-relay.sh \
126 --url http://localhost:8080 \
127 --token "$(./run.sh token)" \
128 --channel general
129 ```
130
131 Manual path:
132
133 ```bash
134 mkdir -p ~/.claude/hooks
135 cp skills/scuttlebot-relay/hooks/scuttlebot-post.sh ~/.claude/hooks/
136 cp skills/scuttlebot-relay/hooks/scuttlebot-check.sh ~/.claude/hooks/
@@ -103,10 +155,25 @@
155 }
156 ]
157 }
158 }
159 ```
160
161 Install the compiled broker if you want startup/offline presence plus continuous
162 IRC input injection:
163
164 ```bash
165 mkdir -p ~/.local/bin
166 go build -o ~/.local/bin/claude-relay ./cmd/claude-relay
167 chmod +x ~/.local/bin/claude-relay
168 ```
169
170 Launch with:
171
172 ```bash
173 ~/.local/bin/claude-relay
174 ```
175
176 ## Blocking semantics
177
178 Only addressed instructions block the loop.
179
@@ -139,7 +206,8 @@
206 ## Operational notes
207
208 - These hooks talk to the scuttlebot HTTP API, not raw IRC.
209 - If scuttlebot is down or unreachable, the hooks soft-fail and return quickly.
210 - `SCUTTLEBOT_HOOKS_ENABLED=0` disables both hooks explicitly.
211 - `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` suppresses `scuttlebot-post.sh` when the broker is already mirroring activity.
212 - They should remain in the repo as installable reference files.
213 - Do not bake tokens into the scripts. Use environment variables.
214
--- skills/scuttlebot-relay/hooks/scuttlebot-post.sh
+++ skills/scuttlebot-relay/hooks/scuttlebot-post.sh
@@ -11,10 +11,11 @@
1111
1212
SCUTTLEBOT_URL="${SCUTTLEBOT_URL:-http://localhost:8080}"
1313
SCUTTLEBOT_TOKEN="${SCUTTLEBOT_TOKEN}"
1414
SCUTTLEBOT_CHANNEL="${SCUTTLEBOT_CHANNEL:-general}"
1515
SCUTTLEBOT_HOOKS_ENABLED="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
16
+SCUTTLEBOT_ACTIVITY_VIA_BROKER="${SCUTTLEBOT_ACTIVITY_VIA_BROKER:-0}"
1617
1718
input=$(cat)
1819
1920
tool=$(echo "$input" | jq -r '.tool_name // empty')
2021
cwd=$(echo "$input" | jq -r '.cwd // empty')
@@ -32,10 +33,12 @@
3233
default_nick="claude-${base_name}-${session_suffix}"
3334
SCUTTLEBOT_NICK="${SCUTTLEBOT_NICK:-$default_nick}"
3435
3536
[ "$SCUTTLEBOT_HOOKS_ENABLED" = "0" ] && exit 0
3637
[ "$SCUTTLEBOT_HOOKS_ENABLED" = "false" ] && exit 0
38
+[ "$SCUTTLEBOT_ACTIVITY_VIA_BROKER" = "1" ] && exit 0
39
+[ "$SCUTTLEBOT_ACTIVITY_VIA_BROKER" = "true" ] && exit 0
3740
[ -z "$SCUTTLEBOT_TOKEN" ] && exit 0
3841
3942
case "$tool" in
4043
Bash)
4144
cmd=$(echo "$input" | jq -r '.tool_input.command // empty' | head -c 120)
4245
--- skills/scuttlebot-relay/hooks/scuttlebot-post.sh
+++ skills/scuttlebot-relay/hooks/scuttlebot-post.sh
@@ -11,10 +11,11 @@
11
12 SCUTTLEBOT_URL="${SCUTTLEBOT_URL:-http://localhost:8080}"
13 SCUTTLEBOT_TOKEN="${SCUTTLEBOT_TOKEN}"
14 SCUTTLEBOT_CHANNEL="${SCUTTLEBOT_CHANNEL:-general}"
15 SCUTTLEBOT_HOOKS_ENABLED="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
 
16
17 input=$(cat)
18
19 tool=$(echo "$input" | jq -r '.tool_name // empty')
20 cwd=$(echo "$input" | jq -r '.cwd // empty')
@@ -32,10 +33,12 @@
32 default_nick="claude-${base_name}-${session_suffix}"
33 SCUTTLEBOT_NICK="${SCUTTLEBOT_NICK:-$default_nick}"
34
35 [ "$SCUTTLEBOT_HOOKS_ENABLED" = "0" ] && exit 0
36 [ "$SCUTTLEBOT_HOOKS_ENABLED" = "false" ] && exit 0
 
 
37 [ -z "$SCUTTLEBOT_TOKEN" ] && exit 0
38
39 case "$tool" in
40 Bash)
41 cmd=$(echo "$input" | jq -r '.tool_input.command // empty' | head -c 120)
42
--- skills/scuttlebot-relay/hooks/scuttlebot-post.sh
+++ skills/scuttlebot-relay/hooks/scuttlebot-post.sh
@@ -11,10 +11,11 @@
11
12 SCUTTLEBOT_URL="${SCUTTLEBOT_URL:-http://localhost:8080}"
13 SCUTTLEBOT_TOKEN="${SCUTTLEBOT_TOKEN}"
14 SCUTTLEBOT_CHANNEL="${SCUTTLEBOT_CHANNEL:-general}"
15 SCUTTLEBOT_HOOKS_ENABLED="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
16 SCUTTLEBOT_ACTIVITY_VIA_BROKER="${SCUTTLEBOT_ACTIVITY_VIA_BROKER:-0}"
17
18 input=$(cat)
19
20 tool=$(echo "$input" | jq -r '.tool_name // empty')
21 cwd=$(echo "$input" | jq -r '.cwd // empty')
@@ -32,10 +33,12 @@
33 default_nick="claude-${base_name}-${session_suffix}"
34 SCUTTLEBOT_NICK="${SCUTTLEBOT_NICK:-$default_nick}"
35
36 [ "$SCUTTLEBOT_HOOKS_ENABLED" = "0" ] && exit 0
37 [ "$SCUTTLEBOT_HOOKS_ENABLED" = "false" ] && exit 0
38 [ "$SCUTTLEBOT_ACTIVITY_VIA_BROKER" = "1" ] && exit 0
39 [ "$SCUTTLEBOT_ACTIVITY_VIA_BROKER" = "true" ] && exit 0
40 [ -z "$SCUTTLEBOT_TOKEN" ] && exit 0
41
42 case "$tool" in
43 Bash)
44 cmd=$(echo "$input" | jq -r '.tool_input.command // empty' | head -c 120)
45
--- skills/scuttlebot-relay/install.md
+++ skills/scuttlebot-relay/install.md
@@ -48,10 +48,11 @@
4848
4949
## Behavior
5050
5151
- **Ambient Chat:** Unaddressed chat in the channel does not interrupt your work.
5252
- **Operator Instruction:** Mention your session's nick to interrupt and provide guidance.
53
+- **IRC Auth:** Leave `SCUTTLEBOT_IRC_PASS` unset for the default auto-registration path. Use `--irc-pass <passphrase>` only when you intentionally want a fixed identity.
5354
- **Fallbacks:** If the relay server is down, Claude still runs normally; you just lose the IRC coordination layer.
5455
5556
## Configuration
5657
5758
Useful shared env knobs in `~/.config/scuttlebot-relay.env`:
5859
--- skills/scuttlebot-relay/install.md
+++ skills/scuttlebot-relay/install.md
@@ -48,10 +48,11 @@
48
49 ## Behavior
50
51 - **Ambient Chat:** Unaddressed chat in the channel does not interrupt your work.
52 - **Operator Instruction:** Mention your session's nick to interrupt and provide guidance.
 
53 - **Fallbacks:** If the relay server is down, Claude still runs normally; you just lose the IRC coordination layer.
54
55 ## Configuration
56
57 Useful shared env knobs in `~/.config/scuttlebot-relay.env`:
58
--- skills/scuttlebot-relay/install.md
+++ skills/scuttlebot-relay/install.md
@@ -48,10 +48,11 @@
48
49 ## Behavior
50
51 - **Ambient Chat:** Unaddressed chat in the channel does not interrupt your work.
52 - **Operator Instruction:** Mention your session's nick to interrupt and provide guidance.
53 - **IRC Auth:** Leave `SCUTTLEBOT_IRC_PASS` unset for the default auto-registration path. Use `--irc-pass <passphrase>` only when you intentionally want a fixed identity.
54 - **Fallbacks:** If the relay server is down, Claude still runs normally; you just lose the IRC coordination layer.
55
56 ## Configuration
57
58 Useful shared env knobs in `~/.config/scuttlebot-relay.env`:
59
--- skills/scuttlebot-relay/scripts/install-claude-relay.sh
+++ skills/scuttlebot-relay/scripts/install-claude-relay.sh
@@ -10,10 +10,14 @@
1010
1111
Options:
1212
--url URL Set SCUTTLEBOT_URL in the shared env file.
1313
--token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
1414
--channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
15
+ --transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: irc.
16
+ --irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
17
+ --irc-pass PASS Write SCUTTLEBOT_IRC_PASS for fixed-identity IRC mode.
18
+ --auto-register Remove SCUTTLEBOT_IRC_PASS so IRC mode auto-registers session nicks. Default.
1519
--enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
1620
--disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
1721
--config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
1822
--hooks-dir PATH Claude hooks install dir. Default: ~/.claude/hooks
1923
--settings-json PATH Claude settings JSON. Default: ~/.claude/settings.json
@@ -22,11 +26,18 @@
2226
2327
Environment defaults:
2428
SCUTTLEBOT_URL
2529
SCUTTLEBOT_TOKEN
2630
SCUTTLEBOT_CHANNEL
31
+ SCUTTLEBOT_TRANSPORT
32
+ SCUTTLEBOT_IRC_ADDR
33
+ SCUTTLEBOT_IRC_PASS
34
+ SCUTTLEBOT_IRC_DELETE_ON_CLOSE
2735
SCUTTLEBOT_HOOKS_ENABLED
36
+ SCUTTLEBOT_INTERRUPT_ON_MESSAGE
37
+ SCUTTLEBOT_POLL_INTERVAL
38
+ SCUTTLEBOT_PRESENCE_HEARTBEAT
2839
SCUTTLEBOT_CONFIG_FILE
2940
CLAUDE_HOOKS_DIR
3041
CLAUDE_SETTINGS_JSON
3142
CLAUDE_BIN_DIR
3243
@@ -44,11 +55,24 @@
4455
REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../../.." && pwd)
4556
4657
SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
4758
SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
4859
SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
60
+SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-irc}"
61
+SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
62
+if [ -n "${SCUTTLEBOT_IRC_PASS:-}" ]; then
63
+ SCUTTLEBOT_IRC_PASS_MODE="fixed"
64
+ SCUTTLEBOT_IRC_PASS_VALUE="$SCUTTLEBOT_IRC_PASS"
65
+else
66
+ SCUTTLEBOT_IRC_PASS_MODE="auto"
67
+ SCUTTLEBOT_IRC_PASS_VALUE=""
68
+fi
69
+SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE="${SCUTTLEBOT_IRC_DELETE_ON_CLOSE:-1}"
4970
SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
71
+SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
72
+SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
73
+SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
5074
5175
CONFIG_FILE="${SCUTTLEBOT_CONFIG_FILE:-$HOME/.config/scuttlebot-relay.env}"
5276
HOOKS_DIR="${CLAUDE_HOOKS_DIR:-$HOME/.claude/hooks}"
5377
SETTINGS_JSON="${CLAUDE_SETTINGS_JSON:-$HOME/.claude/settings.json}"
5478
BIN_DIR="${CLAUDE_BIN_DIR:-$HOME/.local/bin}"
@@ -64,10 +88,28 @@
6488
shift 2
6589
;;
6690
--channel)
6791
SCUTTLEBOT_CHANNEL_VALUE="${2:?missing value for --channel}"
6892
shift 2
93
+ ;;
94
+ --transport)
95
+ SCUTTLEBOT_TRANSPORT_VALUE="${2:?missing value for --transport}"
96
+ shift 2
97
+ ;;
98
+ --irc-addr)
99
+ SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
100
+ shift 2
101
+ ;;
102
+ --irc-pass)
103
+ SCUTTLEBOT_IRC_PASS_MODE="fixed"
104
+ SCUTTLEBOT_IRC_PASS_VALUE="${2:?missing value for --irc-pass}"
105
+ shift 2
106
+ ;;
107
+ --auto-register)
108
+ SCUTTLEBOT_IRC_PASS_MODE="auto"
109
+ SCUTTLEBOT_IRC_PASS_VALUE=""
110
+ shift
69111
;;
70112
--enabled)
71113
SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
72114
shift
73115
;;
@@ -140,10 +182,20 @@
140182
END {
141183
if (!done) {
142184
print key "=" value
143185
}
144186
}
187
+ ' "$file" > "${file}.tmp"
188
+ mv "${file}.tmp" "$file"
189
+}
190
+
191
+remove_env_var() {
192
+ local file="$1"
193
+ local key="$2"
194
+ awk -v key="$key" '
195
+ $0 ~ "^(export[[:space:]]+)?" key "=" { next }
196
+ { print }
145197
' "$file" > "${file}.tmp"
146198
mv "${file}.tmp" "$file"
147199
}
148200
149201
need_cmd jq
@@ -225,20 +277,32 @@
225277
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TOKEN "$SCUTTLEBOT_TOKEN_VALUE"
226278
fi
227279
if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
228280
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
229281
fi
282
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
283
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
284
+if [ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ]; then
285
+ upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
286
+else
287
+ remove_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS
288
+fi
289
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_DELETE_ON_CLOSE "$SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE"
230290
upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
291
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
292
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
293
+upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
231294
232295
printf 'Installed Claude relay files:\n'
233296
printf ' hooks: %s\n' "$HOOKS_DIR"
234297
printf ' settings: %s\n' "$SETTINGS_JSON"
235298
printf ' launcher: %s\n' "$LAUNCHER_DST"
236299
printf ' env: %s\n' "$CONFIG_FILE"
300
+printf ' irc auth: %s\n' "$([ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ] && printf 'fixed-pass override' || printf 'auto-register')"
237301
printf '\n'
238302
printf 'Next steps:\n'
239303
printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
240304
printf ' 2. Watch IRC for: claude-{repo}-{session}\n'
241305
printf ' 3. Mention that nick to interrupt before the next action\n'
242306
printf '\n'
243307
printf 'Disable without uninstalling:\n'
244308
printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
245309
--- skills/scuttlebot-relay/scripts/install-claude-relay.sh
+++ skills/scuttlebot-relay/scripts/install-claude-relay.sh
@@ -10,10 +10,14 @@
10
11 Options:
12 --url URL Set SCUTTLEBOT_URL in the shared env file.
13 --token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
14 --channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
 
 
 
 
15 --enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
16 --disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
17 --config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
18 --hooks-dir PATH Claude hooks install dir. Default: ~/.claude/hooks
19 --settings-json PATH Claude settings JSON. Default: ~/.claude/settings.json
@@ -22,11 +26,18 @@
22
23 Environment defaults:
24 SCUTTLEBOT_URL
25 SCUTTLEBOT_TOKEN
26 SCUTTLEBOT_CHANNEL
 
 
 
 
27 SCUTTLEBOT_HOOKS_ENABLED
 
 
 
28 SCUTTLEBOT_CONFIG_FILE
29 CLAUDE_HOOKS_DIR
30 CLAUDE_SETTINGS_JSON
31 CLAUDE_BIN_DIR
32
@@ -44,11 +55,24 @@
44 REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../../.." && pwd)
45
46 SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
47 SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
48 SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
 
 
 
 
 
 
 
 
 
 
49 SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
 
 
 
50
51 CONFIG_FILE="${SCUTTLEBOT_CONFIG_FILE:-$HOME/.config/scuttlebot-relay.env}"
52 HOOKS_DIR="${CLAUDE_HOOKS_DIR:-$HOME/.claude/hooks}"
53 SETTINGS_JSON="${CLAUDE_SETTINGS_JSON:-$HOME/.claude/settings.json}"
54 BIN_DIR="${CLAUDE_BIN_DIR:-$HOME/.local/bin}"
@@ -64,10 +88,28 @@
64 shift 2
65 ;;
66 --channel)
67 SCUTTLEBOT_CHANNEL_VALUE="${2:?missing value for --channel}"
68 shift 2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69 ;;
70 --enabled)
71 SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
72 shift
73 ;;
@@ -140,10 +182,20 @@
140 END {
141 if (!done) {
142 print key "=" value
143 }
144 }
 
 
 
 
 
 
 
 
 
 
145 ' "$file" > "${file}.tmp"
146 mv "${file}.tmp" "$file"
147 }
148
149 need_cmd jq
@@ -225,20 +277,32 @@
225 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TOKEN "$SCUTTLEBOT_TOKEN_VALUE"
226 fi
227 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
228 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
229 fi
 
 
 
 
 
 
 
 
230 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
 
 
 
231
232 printf 'Installed Claude relay files:\n'
233 printf ' hooks: %s\n' "$HOOKS_DIR"
234 printf ' settings: %s\n' "$SETTINGS_JSON"
235 printf ' launcher: %s\n' "$LAUNCHER_DST"
236 printf ' env: %s\n' "$CONFIG_FILE"
 
237 printf '\n'
238 printf 'Next steps:\n'
239 printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
240 printf ' 2. Watch IRC for: claude-{repo}-{session}\n'
241 printf ' 3. Mention that nick to interrupt before the next action\n'
242 printf '\n'
243 printf 'Disable without uninstalling:\n'
244 printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
245
--- skills/scuttlebot-relay/scripts/install-claude-relay.sh
+++ skills/scuttlebot-relay/scripts/install-claude-relay.sh
@@ -10,10 +10,14 @@
10
11 Options:
12 --url URL Set SCUTTLEBOT_URL in the shared env file.
13 --token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
14 --channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
15 --transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: irc.
16 --irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
17 --irc-pass PASS Write SCUTTLEBOT_IRC_PASS for fixed-identity IRC mode.
18 --auto-register Remove SCUTTLEBOT_IRC_PASS so IRC mode auto-registers session nicks. Default.
19 --enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
20 --disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
21 --config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
22 --hooks-dir PATH Claude hooks install dir. Default: ~/.claude/hooks
23 --settings-json PATH Claude settings JSON. Default: ~/.claude/settings.json
@@ -22,11 +26,18 @@
26
27 Environment defaults:
28 SCUTTLEBOT_URL
29 SCUTTLEBOT_TOKEN
30 SCUTTLEBOT_CHANNEL
31 SCUTTLEBOT_TRANSPORT
32 SCUTTLEBOT_IRC_ADDR
33 SCUTTLEBOT_IRC_PASS
34 SCUTTLEBOT_IRC_DELETE_ON_CLOSE
35 SCUTTLEBOT_HOOKS_ENABLED
36 SCUTTLEBOT_INTERRUPT_ON_MESSAGE
37 SCUTTLEBOT_POLL_INTERVAL
38 SCUTTLEBOT_PRESENCE_HEARTBEAT
39 SCUTTLEBOT_CONFIG_FILE
40 CLAUDE_HOOKS_DIR
41 CLAUDE_SETTINGS_JSON
42 CLAUDE_BIN_DIR
43
@@ -44,11 +55,24 @@
55 REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../../.." && pwd)
56
57 SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
58 SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
59 SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
60 SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-irc}"
61 SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
62 if [ -n "${SCUTTLEBOT_IRC_PASS:-}" ]; then
63 SCUTTLEBOT_IRC_PASS_MODE="fixed"
64 SCUTTLEBOT_IRC_PASS_VALUE="$SCUTTLEBOT_IRC_PASS"
65 else
66 SCUTTLEBOT_IRC_PASS_MODE="auto"
67 SCUTTLEBOT_IRC_PASS_VALUE=""
68 fi
69 SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE="${SCUTTLEBOT_IRC_DELETE_ON_CLOSE:-1}"
70 SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
71 SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
72 SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
73 SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
74
75 CONFIG_FILE="${SCUTTLEBOT_CONFIG_FILE:-$HOME/.config/scuttlebot-relay.env}"
76 HOOKS_DIR="${CLAUDE_HOOKS_DIR:-$HOME/.claude/hooks}"
77 SETTINGS_JSON="${CLAUDE_SETTINGS_JSON:-$HOME/.claude/settings.json}"
78 BIN_DIR="${CLAUDE_BIN_DIR:-$HOME/.local/bin}"
@@ -64,10 +88,28 @@
88 shift 2
89 ;;
90 --channel)
91 SCUTTLEBOT_CHANNEL_VALUE="${2:?missing value for --channel}"
92 shift 2
93 ;;
94 --transport)
95 SCUTTLEBOT_TRANSPORT_VALUE="${2:?missing value for --transport}"
96 shift 2
97 ;;
98 --irc-addr)
99 SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
100 shift 2
101 ;;
102 --irc-pass)
103 SCUTTLEBOT_IRC_PASS_MODE="fixed"
104 SCUTTLEBOT_IRC_PASS_VALUE="${2:?missing value for --irc-pass}"
105 shift 2
106 ;;
107 --auto-register)
108 SCUTTLEBOT_IRC_PASS_MODE="auto"
109 SCUTTLEBOT_IRC_PASS_VALUE=""
110 shift
111 ;;
112 --enabled)
113 SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
114 shift
115 ;;
@@ -140,10 +182,20 @@
182 END {
183 if (!done) {
184 print key "=" value
185 }
186 }
187 ' "$file" > "${file}.tmp"
188 mv "${file}.tmp" "$file"
189 }
190
191 remove_env_var() {
192 local file="$1"
193 local key="$2"
194 awk -v key="$key" '
195 $0 ~ "^(export[[:space:]]+)?" key "=" { next }
196 { print }
197 ' "$file" > "${file}.tmp"
198 mv "${file}.tmp" "$file"
199 }
200
201 need_cmd jq
@@ -225,20 +277,32 @@
277 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TOKEN "$SCUTTLEBOT_TOKEN_VALUE"
278 fi
279 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
280 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
281 fi
282 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
283 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
284 if [ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ]; then
285 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
286 else
287 remove_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS
288 fi
289 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_DELETE_ON_CLOSE "$SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE"
290 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
291 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
292 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
293 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
294
295 printf 'Installed Claude relay files:\n'
296 printf ' hooks: %s\n' "$HOOKS_DIR"
297 printf ' settings: %s\n' "$SETTINGS_JSON"
298 printf ' launcher: %s\n' "$LAUNCHER_DST"
299 printf ' env: %s\n' "$CONFIG_FILE"
300 printf ' irc auth: %s\n' "$([ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ] && printf 'fixed-pass override' || printf 'auto-register')"
301 printf '\n'
302 printf 'Next steps:\n'
303 printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
304 printf ' 2. Watch IRC for: claude-{repo}-{session}\n'
305 printf ' 3. Mention that nick to interrupt before the next action\n'
306 printf '\n'
307 printf 'Disable without uninstalling:\n'
308 printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"
309
--- tests/smoke/test-installers.sh
+++ tests/smoke/test-installers.sh
@@ -17,10 +17,15 @@
1717
export CLAUDE_HOOKS_DIR="$HOME/.claude/hooks"
1818
export CLAUDE_SETTINGS_JSON="$HOME/.claude/settings.json"
1919
export CLAUDE_BIN_DIR="$HOME/.local/bin"
2020
2121
printf 'Smoke testing installers in %s...\n' "$TEMP_HOME"
22
+
23
+mkdir -p "$HOME/.config"
24
+cat > "$SCUTTLEBOT_CONFIG_FILE" <<'EOF'
25
+SCUTTLEBOT_IRC_PASS=stale-pass
26
+EOF
2227
2328
# Mock binaries
2429
mkdir -p "$HOME/.local/bin"
2530
touch "$HOME/.local/bin/codex" "$HOME/.local/bin/gemini" "$HOME/.local/bin/claude"
2631
chmod +x "$HOME/.local/bin/codex" "$HOME/.local/bin/gemini" "$HOME/.local/bin/claude"
@@ -38,35 +43,56 @@
3843
[ -f "$HOME/.codex/hooks/scuttlebot-check.sh" ]
3944
[ -f "$HOME/.codex/hooks.json" ]
4045
[ -f "$HOME/.codex/config.toml" ]
4146
[ -f "$HOME/.local/bin/codex-relay" ]
4247
[ -f "$HOME/.config/scuttlebot-relay.env" ]
48
+! grep -q '^SCUTTLEBOT_IRC_PASS=' "$SCUTTLEBOT_CONFIG_FILE"
49
+grep -q '^SCUTTLEBOT_IRC_DELETE_ON_CLOSE=1$' "$SCUTTLEBOT_CONFIG_FILE"
4350
4451
# 2. Gemini
4552
printf 'Testing Gemini installer...\n'
4653
bash "$REPO_ROOT/skills/gemini-relay/scripts/install-gemini-relay.sh" \
4754
--url http://localhost:8080 \
4855
--token "test-token" \
49
- --channel general
56
+ --channel general \
57
+ --irc-pass "gemini-fixed"
5058
5159
# Verify files
5260
[ -f "$HOME/.gemini/hooks/scuttlebot-post.sh" ]
5361
[ -f "$HOME/.gemini/hooks/scuttlebot-check.sh" ]
5462
[ -f "$HOME/.gemini/settings.json" ]
5563
[ -f "$HOME/.local/bin/gemini-relay" ]
64
+grep -q '^SCUTTLEBOT_IRC_PASS=gemini-fixed$' "$SCUTTLEBOT_CONFIG_FILE"
65
+
66
+printf 'Testing Gemini auto-register scrub...\n'
67
+bash "$REPO_ROOT/skills/gemini-relay/scripts/install-gemini-relay.sh" \
68
+ --channel general \
69
+ --auto-register
70
+! grep -q '^SCUTTLEBOT_IRC_PASS=' "$SCUTTLEBOT_CONFIG_FILE"
5671
5772
# 3. Claude
5873
printf 'Testing Claude installer...\n'
5974
bash "$REPO_ROOT/skills/scuttlebot-relay/scripts/install-claude-relay.sh" \
6075
--url http://localhost:8080 \
6176
--token "test-token" \
62
- --channel general
77
+ --channel general \
78
+ --transport irc \
79
+ --irc-addr 127.0.0.1:6667 \
80
+ --irc-pass "claude-fixed"
6381
6482
# Verify files
6583
[ -f "$HOME/.claude/hooks/scuttlebot-post.sh" ]
6684
[ -f "$HOME/.claude/hooks/scuttlebot-check.sh" ]
6785
[ -f "$HOME/.claude/settings.json" ]
6886
[ -f "$HOME/.local/bin/claude-relay" ]
87
+grep -q '^SCUTTLEBOT_IRC_PASS=claude-fixed$' "$SCUTTLEBOT_CONFIG_FILE"
88
+grep -q '^SCUTTLEBOT_TRANSPORT=irc$' "$SCUTTLEBOT_CONFIG_FILE"
89
+
90
+printf 'Testing Claude auto-register scrub...\n'
91
+bash "$REPO_ROOT/skills/scuttlebot-relay/scripts/install-claude-relay.sh" \
92
+ --channel general \
93
+ --auto-register
94
+! grep -q '^SCUTTLEBOT_IRC_PASS=' "$SCUTTLEBOT_CONFIG_FILE"
6995
7096
printf 'ALL INSTALLERS PASSED SMOKE TEST\n'
7197
chmod -R +w "$TEMP_HOME"
7298
rm -rf "$TEMP_HOME"
7399
--- tests/smoke/test-installers.sh
+++ tests/smoke/test-installers.sh
@@ -17,10 +17,15 @@
17 export CLAUDE_HOOKS_DIR="$HOME/.claude/hooks"
18 export CLAUDE_SETTINGS_JSON="$HOME/.claude/settings.json"
19 export CLAUDE_BIN_DIR="$HOME/.local/bin"
20
21 printf 'Smoke testing installers in %s...\n' "$TEMP_HOME"
 
 
 
 
 
22
23 # Mock binaries
24 mkdir -p "$HOME/.local/bin"
25 touch "$HOME/.local/bin/codex" "$HOME/.local/bin/gemini" "$HOME/.local/bin/claude"
26 chmod +x "$HOME/.local/bin/codex" "$HOME/.local/bin/gemini" "$HOME/.local/bin/claude"
@@ -38,35 +43,56 @@
38 [ -f "$HOME/.codex/hooks/scuttlebot-check.sh" ]
39 [ -f "$HOME/.codex/hooks.json" ]
40 [ -f "$HOME/.codex/config.toml" ]
41 [ -f "$HOME/.local/bin/codex-relay" ]
42 [ -f "$HOME/.config/scuttlebot-relay.env" ]
 
 
43
44 # 2. Gemini
45 printf 'Testing Gemini installer...\n'
46 bash "$REPO_ROOT/skills/gemini-relay/scripts/install-gemini-relay.sh" \
47 --url http://localhost:8080 \
48 --token "test-token" \
49 --channel general
 
50
51 # Verify files
52 [ -f "$HOME/.gemini/hooks/scuttlebot-post.sh" ]
53 [ -f "$HOME/.gemini/hooks/scuttlebot-check.sh" ]
54 [ -f "$HOME/.gemini/settings.json" ]
55 [ -f "$HOME/.local/bin/gemini-relay" ]
 
 
 
 
 
 
 
56
57 # 3. Claude
58 printf 'Testing Claude installer...\n'
59 bash "$REPO_ROOT/skills/scuttlebot-relay/scripts/install-claude-relay.sh" \
60 --url http://localhost:8080 \
61 --token "test-token" \
62 --channel general
 
 
 
63
64 # Verify files
65 [ -f "$HOME/.claude/hooks/scuttlebot-post.sh" ]
66 [ -f "$HOME/.claude/hooks/scuttlebot-check.sh" ]
67 [ -f "$HOME/.claude/settings.json" ]
68 [ -f "$HOME/.local/bin/claude-relay" ]
 
 
 
 
 
 
 
 
69
70 printf 'ALL INSTALLERS PASSED SMOKE TEST\n'
71 chmod -R +w "$TEMP_HOME"
72 rm -rf "$TEMP_HOME"
73
--- tests/smoke/test-installers.sh
+++ tests/smoke/test-installers.sh
@@ -17,10 +17,15 @@
17 export CLAUDE_HOOKS_DIR="$HOME/.claude/hooks"
18 export CLAUDE_SETTINGS_JSON="$HOME/.claude/settings.json"
19 export CLAUDE_BIN_DIR="$HOME/.local/bin"
20
21 printf 'Smoke testing installers in %s...\n' "$TEMP_HOME"
22
23 mkdir -p "$HOME/.config"
24 cat > "$SCUTTLEBOT_CONFIG_FILE" <<'EOF'
25 SCUTTLEBOT_IRC_PASS=stale-pass
26 EOF
27
28 # Mock binaries
29 mkdir -p "$HOME/.local/bin"
30 touch "$HOME/.local/bin/codex" "$HOME/.local/bin/gemini" "$HOME/.local/bin/claude"
31 chmod +x "$HOME/.local/bin/codex" "$HOME/.local/bin/gemini" "$HOME/.local/bin/claude"
@@ -38,35 +43,56 @@
43 [ -f "$HOME/.codex/hooks/scuttlebot-check.sh" ]
44 [ -f "$HOME/.codex/hooks.json" ]
45 [ -f "$HOME/.codex/config.toml" ]
46 [ -f "$HOME/.local/bin/codex-relay" ]
47 [ -f "$HOME/.config/scuttlebot-relay.env" ]
48 ! grep -q '^SCUTTLEBOT_IRC_PASS=' "$SCUTTLEBOT_CONFIG_FILE"
49 grep -q '^SCUTTLEBOT_IRC_DELETE_ON_CLOSE=1$' "$SCUTTLEBOT_CONFIG_FILE"
50
51 # 2. Gemini
52 printf 'Testing Gemini installer...\n'
53 bash "$REPO_ROOT/skills/gemini-relay/scripts/install-gemini-relay.sh" \
54 --url http://localhost:8080 \
55 --token "test-token" \
56 --channel general \
57 --irc-pass "gemini-fixed"
58
59 # Verify files
60 [ -f "$HOME/.gemini/hooks/scuttlebot-post.sh" ]
61 [ -f "$HOME/.gemini/hooks/scuttlebot-check.sh" ]
62 [ -f "$HOME/.gemini/settings.json" ]
63 [ -f "$HOME/.local/bin/gemini-relay" ]
64 grep -q '^SCUTTLEBOT_IRC_PASS=gemini-fixed$' "$SCUTTLEBOT_CONFIG_FILE"
65
66 printf 'Testing Gemini auto-register scrub...\n'
67 bash "$REPO_ROOT/skills/gemini-relay/scripts/install-gemini-relay.sh" \
68 --channel general \
69 --auto-register
70 ! grep -q '^SCUTTLEBOT_IRC_PASS=' "$SCUTTLEBOT_CONFIG_FILE"
71
72 # 3. Claude
73 printf 'Testing Claude installer...\n'
74 bash "$REPO_ROOT/skills/scuttlebot-relay/scripts/install-claude-relay.sh" \
75 --url http://localhost:8080 \
76 --token "test-token" \
77 --channel general \
78 --transport irc \
79 --irc-addr 127.0.0.1:6667 \
80 --irc-pass "claude-fixed"
81
82 # Verify files
83 [ -f "$HOME/.claude/hooks/scuttlebot-post.sh" ]
84 [ -f "$HOME/.claude/hooks/scuttlebot-check.sh" ]
85 [ -f "$HOME/.claude/settings.json" ]
86 [ -f "$HOME/.local/bin/claude-relay" ]
87 grep -q '^SCUTTLEBOT_IRC_PASS=claude-fixed$' "$SCUTTLEBOT_CONFIG_FILE"
88 grep -q '^SCUTTLEBOT_TRANSPORT=irc$' "$SCUTTLEBOT_CONFIG_FILE"
89
90 printf 'Testing Claude auto-register scrub...\n'
91 bash "$REPO_ROOT/skills/scuttlebot-relay/scripts/install-claude-relay.sh" \
92 --channel general \
93 --auto-register
94 ! grep -q '^SCUTTLEBOT_IRC_PASS=' "$SCUTTLEBOT_CONFIG_FILE"
95
96 printf 'ALL INSTALLERS PASSED SMOKE TEST\n'
97 chmod -R +w "$TEMP_HOME"
98 rm -rf "$TEMP_HOME"
99

Keyboard Shortcuts

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