1
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Codex Hook Primer
2
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
3
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
These hooks are the pre-tool fallback path for a live Codex tool loop.
4
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Continuous IRC-to-terminal input plus outbound message and tool mirroring are
5
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
handled by the compiled `cmd/codex-relay` broker, which now sits on the shared
6
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
`pkg/sessionrelay` connector package.
7
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
8
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
If you need to add another runtime later, use
9
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
[`../../scuttlebot-relay/ADDING_AGENTS.md`](../../scuttlebot-relay/ADDING_AGENTS.md)
10
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
as the shared authoring contract.
11
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
12
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Files in this directory:
13
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `scuttlebot-post.sh`
14
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `scuttlebot-check.sh`
15
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
16
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Related launcher:
17
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `../../../cmd/codex-relay/main.go`
18
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `../scripts/codex-relay.sh`
19
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `../scripts/install-codex-relay.sh`
20
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
21
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Source of truth:
22
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- the repo copies in this directory and `../scripts/`
23
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- not the installed copies under `~/.codex/` or `~/.local/bin/`
24
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
25
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## What they do
26
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
27
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
`scuttlebot-post.sh`
28
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- runs after each tool call
29
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- posts a one-line activity summary into a scuttlebot channel when Codex is not launched through `codex-relay`
30
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- uses the session nick as the IRC/web bridge sender nick
31
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
32
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
`scuttlebot-check.sh`
33
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- runs before the next action
34
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- fetches recent channel messages from scuttlebot
35
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- ignores bots and agent status nicks
36
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- blocks only when a human explicitly mentions this session nick
37
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- prints a JSON decision block that Codex can surface into the live tool loop
38
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
39
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
With the broker plus hooks together, you get the full control loop:
40
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
1. `cmd/codex-relay` posts `online`.
41
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
2. `cmd/codex-relay` mirrors assistant output and tool activity from the active session log.
42
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
3. The operator mentions the Codex session nick.
43
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
4. `cmd/codex-relay` injects that IRC message into the live terminal session immediately.
44
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
5. `scuttlebot-check.sh` still blocks before the next tool action if needed.
45
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
46
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
For immediate startup visibility and continuous IRC input injection, launch Codex
47
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
through the compiled broker installed as `~/.local/bin/codex-relay`. The repo
48
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
wrapper `../scripts/codex-relay.sh` is only a development convenience.
49
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
50
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Default nick format
51
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
52
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
If `SCUTTLEBOT_NICK` is unset, the hooks derive a stable session nick:
53
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
54
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```text
55
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
codex-{basename of cwd}-{session id}
56
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
57
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
58
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Session id resolution order:
59
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
1. `SCUTTLEBOT_SESSION_ID`
60
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
2. `CODEX_SESSION_ID`
61
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
3. parent process id (`PPID`)
62
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
63
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Examples:
64
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `codex-scuttlebot-8421`
65
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `codex-calliope-qa`
66
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
67
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
This is deliberate. Multiple Codex sessions in the same repo must not collide.
68
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
69
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Required environment
70
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
71
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Required:
72
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_URL`
73
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_TOKEN`
74
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_CHANNEL`
75
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `curl` and `jq` available on `PATH`
76
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
77
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Optional:
78
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_NICK`
79
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_SESSION_ID`
80
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_CHANNELS`
81
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_CHANNEL_STATE_FILE`
82
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_TRANSPORT`
83
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_IRC_ADDR`
84
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_IRC_PASS`
85
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE`
86
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_HOOKS_ENABLED`
87
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE`
88
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_POLL_INTERVAL`
89
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_PRESENCE_HEARTBEAT`
90
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_CONFIG_FILE`
91
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_ACTIVITY_VIA_BROKER`
92
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
93
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Example:
94
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
95
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
96
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export SCUTTLEBOT_URL=http://localhost:8080
97
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export SCUTTLEBOT_TOKEN=$(./run.sh token)
98
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export SCUTTLEBOT_CHANNEL=general
99
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export SCUTTLEBOT_CHANNELS=general,task-42
100
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
101
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
102
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
The hooks also auto-load a shared relay env file if it exists:
103
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
104
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
105
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
cat > ~/.config/scuttlebot-relay.env <<'EOF'
106
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_URL=http://localhost:8080
107
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_TOKEN=...
108
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_CHANNEL=general
109
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_CHANNELS=general
110
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_TRANSPORT=http
111
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667
112
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_HOOKS_ENABLED=1
113
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
114
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_POLL_INTERVAL=2s
115
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
116
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
EOF
117
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
118
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
119
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Leave `SCUTTLEBOT_IRC_PASS` unset for the default broker convention so IRC mode
120
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
auto-registers ephemeral session nicks. Use `--irc-pass <passphrase>` only when
121
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
you intentionally want a fixed identity.
122
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
123
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Disable the hooks entirely:
124
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
125
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
126
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export SCUTTLEBOT_HOOKS_ENABLED=0
127
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
128
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
129
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Hook config
130
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
131
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Preferred path: run the tracked installer and let it wire the files up for you.
132
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
133
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
134
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
bash skills/openai-relay/scripts/install-codex-relay.sh \
135
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
--url http://localhost:8080 \
136
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
--token "$(./run.sh token)" \
137
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
--channel general \
138
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
--channels general,task-42
139
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
140
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
141
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Manual path:
142
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
143
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Install the scripts:
144
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
145
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
146
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
mkdir -p ~/.codex/hooks
147
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
cp skills/openai-relay/hooks/scuttlebot-post.sh ~/.codex/hooks/
148
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
cp skills/openai-relay/hooks/scuttlebot-check.sh ~/.codex/hooks/
149
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
chmod +x ~/.codex/hooks/scuttlebot-post.sh ~/.codex/hooks/scuttlebot-check.sh
150
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
151
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
152
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Configure native Codex hooks in `~/.codex/hooks.json`:
153
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
154
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```json
155
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{
156
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
"hooks": {
157
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
"pre-tool-use": [
158
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{
159
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
"matcher": "Bash|Edit|Write",
160
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
"hooks": [
161
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{ "type": "command", "command": "$HOME/.codex/hooks/scuttlebot-check.sh" }
162
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
]
163
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
}
164
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
],
165
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
"post-tool-use": [
166
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{
167
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
"matcher": "Bash|Read|Edit|Write|Glob|Grep|Agent",
168
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
"hooks": [
169
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{ "type": "command", "command": "$HOME/.codex/hooks/scuttlebot-post.sh" }
170
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
]
171
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
}
172
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
]
173
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
}
174
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
}
175
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
176
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
177
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Enable the feature in `~/.codex/config.toml`:
178
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
179
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```toml
180
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
[features]
181
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
codex_hooks = true
182
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
183
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
184
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Install the compiled broker if you want startup/offline presence plus continuous
185
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
IRC input injection:
186
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
187
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
188
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
mkdir -p ~/.local/bin
189
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
go build -o ~/.local/bin/codex-relay ./cmd/codex-relay
190
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
chmod +x ~/.local/bin/codex-relay
191
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
192
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
193
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Launch with:
194
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
195
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
196
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
~/.local/bin/codex-relay
197
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
198
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
199
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Optional shell alias:
200
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
201
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
202
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
alias codex="$HOME/.local/bin/codex-relay"
203
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
204
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
205
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Do not replace the real `codex` binary in `PATH` with a shell wrapper.
206
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
207
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Message filtering semantics
208
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
209
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
The check hook only surfaces messages that satisfy all of the following:
210
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- newer than the last check for this session
211
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- not posted by this session nick
212
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- not posted by known service bots
213
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- not posted by `claude-*`, `codex-*`, or `gemini-*` status nicks
214
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- explicitly mention this session nick
215
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
216
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
This is the critical fallback behavior. Ambient channel chat must not halt a live tool loop.
217
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
218
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Examples that block:
219
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
220
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```text
221
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
operator: codex-scuttlebot-8421 stop and re-read the schema
222
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
operator: codex-scuttlebot-8421 wrong file, look at internal/api first
223
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
224
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
225
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Examples that do not block:
226
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
227
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```text
228
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
operator: can someone check the schema
229
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
codex-otherrepo-7712: read internal/config/config.go
230
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
bridge: [operator] hello
231
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
232
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
233
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Per-session state
234
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
235
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
The check hook stores its last-seen timestamp in:
236
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
237
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```text
238
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
/tmp/.scuttlebot-last-check-{checksum}
239
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
240
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
241
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
The checksum is derived from:
242
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- session nick
243
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- current working directory
244
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
245
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Live channel changes come from `SCUTTLEBOT_CHANNEL_STATE_FILE`, which the broker
246
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
rewrites as `/join` and `/part` commands change the current session channel set.
247
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
248
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
That avoids one session consuming another session's instructions.
249
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
250
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Smoke test
251
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
252
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Launcher smoke test:
253
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
254
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
255
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
~/.local/bin/codex-relay --version
256
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
257
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
258
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Expected IRC behavior:
259
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- no relay announcements, because metadata-only invocations skip them
260
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
261
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Hook smoke test:
262
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
263
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Post a synthetic activity event:
264
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
265
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
266
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
printf '{"tool_name":"Read","cwd":"%s","tool_input":{"file_path":"%s/README.md"}}\n' "$PWD" "$PWD" \
267
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| SCUTTLEBOT_URL=http://localhost:8080 \
268
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_TOKEN="$(./run.sh token)" \
269
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_CHANNEL=general \
270
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_SESSION_ID=smoke \
271
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
bash skills/openai-relay/hooks/scuttlebot-post.sh
272
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
273
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
274
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Then mention the expected nick from the operator side:
275
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
276
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
277
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
curl -sf -X POST http://localhost:8080/v1/channels/general/messages \
278
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
-H "Authorization: Bearer $(./run.sh token)" \
279
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
-H "Content-Type: application/json" \
280
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
-d '{"nick":"<your-operator-nick>","text":"codex-scuttlebot-smoke stop and check the bridge TTL"}'
281
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
282
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
283
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Run the check hook:
284
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
285
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
286
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_URL=http://localhost:8080 \
287
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_TOKEN="$(./run.sh token)" \
288
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_CHANNEL=general \
289
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
SCUTTLEBOT_SESSION_ID=smoke \
290
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
bash skills/openai-relay/hooks/scuttlebot-check.sh
291
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
292
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
293
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Expected output:
294
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
295
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```json
296
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{"decision":"block","reason":"[IRC instruction from operator] <your-operator-nick>: codex-scuttlebot-smoke stop and check the bridge TTL"}
297
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
298
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
299
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Operational notes
300
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
301
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `cmd/codex-relay` continuously polls for addressed IRC messages and injects them into the live Codex PTY.
302
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `cmd/codex-relay` can do that over either the HTTP bridge API or a real IRC socket.
303
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `cmd/codex-relay` also tails the active session JSONL and mirrors assistant output plus tool activity into IRC.
304
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=0` disables the automatic busy-session interrupt before injected IRC instructions.
305
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- With the default `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1`, the broker only sends Ctrl-C when Codex appears busy. Idle sessions are injected directly and auto-submitted so the broker does not accidentally quit Codex at the prompt.
306
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_POLL_INTERVAL=1s` changes the broker poll interval.
307
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_TRANSPORT=irc` gives the live session a true IRC presence; `SCUTTLEBOT_IRC_PASS` skips auto-registration if you already manage the NickServ account yourself.
308
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s` keeps quiet HTTP-mode sessions in the active user list without visible chatter.
309
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- The hooks themselves still use the scuttlebot HTTP API, not direct IRC.
310
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- If scuttlebot is down or unreachable, the hooks soft-fail and return quickly.
311
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_HOOKS_ENABLED=0` disables both hooks explicitly.
312
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `SCUTTLEBOT_ACTIVITY_VIA_BROKER=1` suppresses `scuttlebot-post.sh` so broker-launched sessions do not duplicate activity posts.
313
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- `../scripts/install-codex-relay.sh --disabled` writes that disabled state into the shared env file.
314
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- For fleet launch instructions, see [`../FLEET.md`](../FLEET.md).
315
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- They are safe to keep in the repo and copy into home hook directories.
316
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- Do not hardcode bearer tokens into the scripts.
317
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- Restart Codex after enabling `codex_hooks` or changing `~/.codex/hooks.json`.
318
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- If you need a fixed nick for a long-lived session, set `SCUTTLEBOT_NICK`.
319
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- The broker is the right place for session-start/session-stop presence because
320
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Codex hooks only fire around tool events.
321
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!