ScuttleBot

scuttlebot / skills / openai-relay / scripts / install-codex-relay.sh
Source Blame History 433 lines
50baf1a… lmata 1 #!/usr/bin/env bash
50baf1a… lmata 2 # Install the tracked Codex relay hooks plus the compiled broker into a local Codex setup.
50baf1a… lmata 3
50baf1a… lmata 4 set -euo pipefail
50baf1a… lmata 5
50baf1a… lmata 6 usage() {
50baf1a… lmata 7 cat <<'EOF'
50baf1a… lmata 8 Usage:
50baf1a… lmata 9 bash skills/openai-relay/scripts/install-codex-relay.sh [options]
50baf1a… lmata 10
50baf1a… lmata 11 Options:
50baf1a… lmata 12 --url URL Set SCUTTLEBOT_URL in the shared env file.
50baf1a… lmata 13 --token TOKEN Set SCUTTLEBOT_TOKEN in the shared env file.
50baf1a… lmata 14 --channel CHANNEL Set SCUTTLEBOT_CHANNEL in the shared env file.
1d3caa2… lmata 15 --channels CSV Set SCUTTLEBOT_CHANNELS in the shared env file.
24a217e… lmata 16 --transport MODE Set SCUTTLEBOT_TRANSPORT (http or irc). Default: http.
24a217e… lmata 17 --irc-addr ADDR Set SCUTTLEBOT_IRC_ADDR. Default: 127.0.0.1:6667.
b8ce843… lmata 18 --irc-pass PASS Write SCUTTLEBOT_IRC_PASS for fixed-identity IRC mode.
b8ce843… lmata 19 --auto-register Remove SCUTTLEBOT_IRC_PASS so IRC mode auto-registers session nicks. Default.
50baf1a… lmata 20 --enabled Write SCUTTLEBOT_HOOKS_ENABLED=1. Default.
50baf1a… lmata 21 --disabled Write SCUTTLEBOT_HOOKS_ENABLED=0.
50baf1a… lmata 22 --config-file PATH Shared env file path. Default: ~/.config/scuttlebot-relay.env
50baf1a… lmata 23 --hooks-dir PATH Codex hooks install dir. Default: ~/.codex/hooks
50baf1a… lmata 24 --hooks-json PATH Codex hooks config JSON. Default: ~/.codex/hooks.json
50baf1a… lmata 25 --codex-config PATH Codex config TOML. Default: ~/.codex/config.toml
50baf1a… lmata 26 --bin-dir PATH Launcher install dir. Default: ~/.local/bin
50baf1a… lmata 27 --help Show this help.
50baf1a… lmata 28
50baf1a… lmata 29 Environment defaults:
50baf1a… lmata 30 SCUTTLEBOT_URL
50baf1a… lmata 31 SCUTTLEBOT_TOKEN
50baf1a… lmata 32 SCUTTLEBOT_CHANNEL
1d3caa2… lmata 33 SCUTTLEBOT_CHANNELS
24a217e… lmata 34 SCUTTLEBOT_TRANSPORT
24a217e… lmata 35 SCUTTLEBOT_IRC_ADDR
24a217e… lmata 36 SCUTTLEBOT_IRC_PASS
50baf1a… lmata 37 SCUTTLEBOT_HOOKS_ENABLED
50baf1a… lmata 38 SCUTTLEBOT_INTERRUPT_ON_MESSAGE
50baf1a… lmata 39 SCUTTLEBOT_POLL_INTERVAL
24a217e… lmata 40 SCUTTLEBOT_PRESENCE_HEARTBEAT
50baf1a… lmata 41 SCUTTLEBOT_CONFIG_FILE
50baf1a… lmata 42 CODEX_HOOKS_DIR
50baf1a… lmata 43 CODEX_HOOKS_JSON
50baf1a… lmata 44 CODEX_CONFIG_TOML
50baf1a… lmata 45 CODEX_BIN_DIR
50baf1a… lmata 46
50baf1a… lmata 47 Examples:
50baf1a… lmata 48 bash skills/openai-relay/scripts/install-codex-relay.sh \
50baf1a… lmata 49 --url http://localhost:8080 \
50baf1a… lmata 50 --token "$(./run.sh token)" \
50baf1a… lmata 51 --channel general
50baf1a… lmata 52 EOF
50baf1a… lmata 53 }
50baf1a… lmata 54
50baf1a… lmata 55 SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
50baf1a… lmata 56 REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../../.." && pwd)
50baf1a… lmata 57
50baf1a… lmata 58 SCUTTLEBOT_URL_VALUE="${SCUTTLEBOT_URL:-}"
50baf1a… lmata 59 SCUTTLEBOT_TOKEN_VALUE="${SCUTTLEBOT_TOKEN:-}"
50baf1a… lmata 60 SCUTTLEBOT_CHANNEL_VALUE="${SCUTTLEBOT_CHANNEL:-}"
1d3caa2… lmata 61 SCUTTLEBOT_CHANNELS_VALUE="${SCUTTLEBOT_CHANNELS:-}"
24a217e… lmata 62 SCUTTLEBOT_TRANSPORT_VALUE="${SCUTTLEBOT_TRANSPORT:-http}"
24a217e… lmata 63 SCUTTLEBOT_IRC_ADDR_VALUE="${SCUTTLEBOT_IRC_ADDR:-127.0.0.1:6667}"
b8ce843… lmata 64 if [ -n "${SCUTTLEBOT_IRC_PASS:-}" ]; then
b8ce843… lmata 65 SCUTTLEBOT_IRC_PASS_MODE="fixed"
b8ce843… lmata 66 SCUTTLEBOT_IRC_PASS_VALUE="$SCUTTLEBOT_IRC_PASS"
b8ce843… lmata 67 else
b8ce843… lmata 68 SCUTTLEBOT_IRC_PASS_MODE="auto"
b8ce843… lmata 69 SCUTTLEBOT_IRC_PASS_VALUE=""
b8ce843… lmata 70 fi
b8ce843… lmata 71 SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE="${SCUTTLEBOT_IRC_DELETE_ON_CLOSE:-1}"
50baf1a… lmata 72 SCUTTLEBOT_HOOKS_ENABLED_VALUE="${SCUTTLEBOT_HOOKS_ENABLED:-1}"
50baf1a… lmata 73 SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE="${SCUTTLEBOT_INTERRUPT_ON_MESSAGE:-1}"
50baf1a… lmata 74 SCUTTLEBOT_POLL_INTERVAL_VALUE="${SCUTTLEBOT_POLL_INTERVAL:-2s}"
24a217e… lmata 75 SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE="${SCUTTLEBOT_PRESENCE_HEARTBEAT:-60s}"
50baf1a… lmata 76
50baf1a… lmata 77 CONFIG_FILE="${SCUTTLEBOT_CONFIG_FILE:-$HOME/.config/scuttlebot-relay.env}"
50baf1a… lmata 78 HOOKS_DIR="${CODEX_HOOKS_DIR:-$HOME/.codex/hooks}"
50baf1a… lmata 79 HOOKS_JSON="${CODEX_HOOKS_JSON:-$HOME/.codex/hooks.json}"
50baf1a… lmata 80 CODEX_CONFIG="${CODEX_CONFIG_TOML:-$HOME/.codex/config.toml}"
50baf1a… lmata 81 BIN_DIR="${CODEX_BIN_DIR:-$HOME/.local/bin}"
50baf1a… lmata 82
50baf1a… lmata 83 while [ $# -gt 0 ]; do
50baf1a… lmata 84 case "$1" in
50baf1a… lmata 85 --url)
50baf1a… lmata 86 SCUTTLEBOT_URL_VALUE="${2:?missing value for --url}"
50baf1a… lmata 87 shift 2
50baf1a… lmata 88 ;;
50baf1a… lmata 89 --token)
50baf1a… lmata 90 SCUTTLEBOT_TOKEN_VALUE="${2:?missing value for --token}"
50baf1a… lmata 91 shift 2
50baf1a… lmata 92 ;;
50baf1a… lmata 93 --channel)
50baf1a… lmata 94 SCUTTLEBOT_CHANNEL_VALUE="${2:?missing value for --channel}"
1d3caa2… lmata 95 shift 2
1d3caa2… lmata 96 ;;
1d3caa2… lmata 97 --channels)
1d3caa2… lmata 98 SCUTTLEBOT_CHANNELS_VALUE="${2:?missing value for --channels}"
b8ce843… lmata 99 shift 2
b8ce843… lmata 100 ;;
24a217e… lmata 101 --transport)
24a217e… lmata 102 SCUTTLEBOT_TRANSPORT_VALUE="${2:?missing value for --transport}"
24a217e… lmata 103 shift 2
24a217e… lmata 104 ;;
24a217e… lmata 105 --irc-addr)
24a217e… lmata 106 SCUTTLEBOT_IRC_ADDR_VALUE="${2:?missing value for --irc-addr}"
24a217e… lmata 107 shift 2
b8ce843… lmata 108 ;;
b8ce843… lmata 109 --irc-pass)
b8ce843… lmata 110 SCUTTLEBOT_IRC_PASS_MODE="fixed"
b8ce843… lmata 111 SCUTTLEBOT_IRC_PASS_VALUE="${2:?missing value for --irc-pass}"
b8ce843… lmata 112 shift 2
b8ce843… lmata 113 ;;
b8ce843… lmata 114 --auto-register)
b8ce843… lmata 115 SCUTTLEBOT_IRC_PASS_MODE="auto"
b8ce843… lmata 116 SCUTTLEBOT_IRC_PASS_VALUE=""
b8ce843… lmata 117 shift
50baf1a… lmata 118 ;;
50baf1a… lmata 119 --enabled)
50baf1a… lmata 120 SCUTTLEBOT_HOOKS_ENABLED_VALUE=1
50baf1a… lmata 121 shift
50baf1a… lmata 122 ;;
50baf1a… lmata 123 --disabled)
50baf1a… lmata 124 SCUTTLEBOT_HOOKS_ENABLED_VALUE=0
50baf1a… lmata 125 shift
50baf1a… lmata 126 ;;
50baf1a… lmata 127 --config-file)
50baf1a… lmata 128 CONFIG_FILE="${2:?missing value for --config-file}"
50baf1a… lmata 129 shift 2
50baf1a… lmata 130 ;;
50baf1a… lmata 131 --hooks-dir)
50baf1a… lmata 132 HOOKS_DIR="${2:?missing value for --hooks-dir}"
50baf1a… lmata 133 shift 2
50baf1a… lmata 134 ;;
50baf1a… lmata 135 --hooks-json)
50baf1a… lmata 136 HOOKS_JSON="${2:?missing value for --hooks-json}"
50baf1a… lmata 137 shift 2
50baf1a… lmata 138 ;;
50baf1a… lmata 139 --codex-config)
50baf1a… lmata 140 CODEX_CONFIG="${2:?missing value for --codex-config}"
50baf1a… lmata 141 shift 2
50baf1a… lmata 142 ;;
50baf1a… lmata 143 --bin-dir)
50baf1a… lmata 144 BIN_DIR="${2:?missing value for --bin-dir}"
50baf1a… lmata 145 shift 2
50baf1a… lmata 146 ;;
50baf1a… lmata 147 --help|-h)
50baf1a… lmata 148 usage
50baf1a… lmata 149 exit 0
50baf1a… lmata 150 ;;
50baf1a… lmata 151 *)
50baf1a… lmata 152 printf 'install-codex-relay: unknown argument %s\n' "$1" >&2
50baf1a… lmata 153 usage >&2
50baf1a… lmata 154 exit 2
50baf1a… lmata 155 ;;
50baf1a… lmata 156 esac
50baf1a… lmata 157 done
50baf1a… lmata 158
50baf1a… lmata 159 need_cmd() {
50baf1a… lmata 160 if ! command -v "$1" >/dev/null 2>&1; then
50baf1a… lmata 161 printf 'install-codex-relay: required command not found: %s\n' "$1" >&2
50baf1a… lmata 162 exit 1
50baf1a… lmata 163 fi
50baf1a… lmata 164 }
50baf1a… lmata 165
50baf1a… lmata 166 backup_file() {
50baf1a… lmata 167 local path="$1"
50baf1a… lmata 168 if [ -f "$path" ] && [ ! -f "${path}.bak" ]; then
50baf1a… lmata 169 cp "$path" "${path}.bak"
50baf1a… lmata 170 fi
50baf1a… lmata 171 }
50baf1a… lmata 172
50baf1a… lmata 173 ensure_parent_dir() {
50baf1a… lmata 174 mkdir -p "$(dirname "$1")"
50baf1a… lmata 175 }
1d3caa2… lmata 176
1d3caa2… lmata 177 normalize_channels() {
1d3caa2… lmata 178 local primary="$1"
1d3caa2… lmata 179 local raw="$2"
1d3caa2… lmata 180 local IFS=','
1d3caa2… lmata 181 local items=()
1d3caa2… lmata 182 local extra_items=()
1d3caa2… lmata 183 local item channel seen=""
1d3caa2… lmata 184
1d3caa2… lmata 185 if [ -n "$primary" ]; then
1d3caa2… lmata 186 items+=("$primary")
1d3caa2… lmata 187 fi
1d3caa2… lmata 188 if [ -n "$raw" ]; then
1d3caa2… lmata 189 read -r -a extra_items <<< "$raw"
1d3caa2… lmata 190 items+=("${extra_items[@]}")
1d3caa2… lmata 191 fi
1d3caa2… lmata 192
1d3caa2… lmata 193 for item in "${items[@]}"; do
1d3caa2… lmata 194 channel="${item//[$' \t\r\n']/}"
1d3caa2… lmata 195 channel="${channel#\#}"
1d3caa2… lmata 196 [ -n "$channel" ] || continue
1d3caa2… lmata 197 case ",$seen," in
1d3caa2… lmata 198 *,"$channel",*) ;;
1d3caa2… lmata 199 *) seen="${seen:+$seen,}$channel" ;;
1d3caa2… lmata 200 esac
1d3caa2… lmata 201 done
1d3caa2… lmata 202
1d3caa2… lmata 203 printf '%s' "$seen"
1d3caa2… lmata 204 }
1d3caa2… lmata 205
1d3caa2… lmata 206 first_channel() {
1d3caa2… lmata 207 local channels
1d3caa2… lmata 208 channels=$(normalize_channels "" "$1")
1d3caa2… lmata 209 printf '%s' "${channels%%,*}"
1d3caa2… lmata 210 }
1d3caa2… lmata 211
1d3caa2… lmata 212 if [ -z "$SCUTTLEBOT_CHANNEL_VALUE" ] && [ -n "$SCUTTLEBOT_CHANNELS_VALUE" ]; then
1d3caa2… lmata 213 SCUTTLEBOT_CHANNEL_VALUE="$(first_channel "$SCUTTLEBOT_CHANNELS_VALUE")"
1d3caa2… lmata 214 fi
1d3caa2… lmata 215 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
1d3caa2… lmata 216 SCUTTLEBOT_CHANNELS_VALUE="$(normalize_channels "$SCUTTLEBOT_CHANNEL_VALUE" "$SCUTTLEBOT_CHANNELS_VALUE")"
1d3caa2… lmata 217 fi
b8ce843… lmata 218
50baf1a… lmata 219 upsert_env_var() {
50baf1a… lmata 220 local file="$1"
50baf1a… lmata 221 local key="$2"
50baf1a… lmata 222 local value="$3"
50baf1a… lmata 223 local escaped
50baf1a… lmata 224 escaped=$(printf '%q' "$value")
50baf1a… lmata 225 awk -v key="$key" -v value="$escaped" '
50baf1a… lmata 226 BEGIN { done = 0 }
50baf1a… lmata 227 $0 ~ "^(export[[:space:]]+)?" key "=" {
50baf1a… lmata 228 if (!done) {
50baf1a… lmata 229 print key "=" value
50baf1a… lmata 230 done = 1
50baf1a… lmata 231 }
50baf1a… lmata 232 next
50baf1a… lmata 233 }
50baf1a… lmata 234 { print }
50baf1a… lmata 235 END {
50baf1a… lmata 236 if (!done) {
50baf1a… lmata 237 print key "=" value
50baf1a… lmata 238 }
50baf1a… lmata 239 }
b8ce843… lmata 240 ' "$file" > "${file}.tmp"
b8ce843… lmata 241 mv "${file}.tmp" "$file"
b8ce843… lmata 242 }
b8ce843… lmata 243
b8ce843… lmata 244 remove_env_var() {
b8ce843… lmata 245 local file="$1"
b8ce843… lmata 246 local key="$2"
b8ce843… lmata 247 awk -v key="$key" '
b8ce843… lmata 248 $0 ~ "^(export[[:space:]]+)?" key "=" { next }
b8ce843… lmata 249 { print }
50baf1a… lmata 250 ' "$file" > "${file}.tmp"
50baf1a… lmata 251 mv "${file}.tmp" "$file"
50baf1a… lmata 252 }
50baf1a… lmata 253
50baf1a… lmata 254 ensure_codex_hooks_feature() {
50baf1a… lmata 255 local file="$1"
50baf1a… lmata 256 local tmp="${file}.tmp"
50baf1a… lmata 257 if [ ! -f "$file" ]; then
50baf1a… lmata 258 cat > "$tmp" <<'EOF'
50baf1a… lmata 259 [features]
50baf1a… lmata 260 codex_hooks = true
50baf1a… lmata 261 EOF
50baf1a… lmata 262 mv "$tmp" "$file"
50baf1a… lmata 263 return
50baf1a… lmata 264 fi
50baf1a… lmata 265
50baf1a… lmata 266 awk '
50baf1a… lmata 267 BEGIN {
50baf1a… lmata 268 in_features = 0
50baf1a… lmata 269 features_seen = 0
50baf1a… lmata 270 codex_hooks_set = 0
50baf1a… lmata 271 }
50baf1a… lmata 272 /^\[features\][[:space:]]*$/ {
50baf1a… lmata 273 print
50baf1a… lmata 274 in_features = 1
50baf1a… lmata 275 features_seen = 1
50baf1a… lmata 276 next
50baf1a… lmata 277 }
50baf1a… lmata 278 /^\[/ {
50baf1a… lmata 279 if (in_features && !codex_hooks_set) {
50baf1a… lmata 280 print "codex_hooks = true"
50baf1a… lmata 281 codex_hooks_set = 1
50baf1a… lmata 282 }
50baf1a… lmata 283 in_features = 0
50baf1a… lmata 284 print
50baf1a… lmata 285 next
50baf1a… lmata 286 }
50baf1a… lmata 287 {
50baf1a… lmata 288 if (in_features && $0 ~ /^[[:space:]]*codex_hooks[[:space:]]*=/) {
50baf1a… lmata 289 if (!codex_hooks_set) {
50baf1a… lmata 290 print "codex_hooks = true"
50baf1a… lmata 291 codex_hooks_set = 1
50baf1a… lmata 292 }
50baf1a… lmata 293 next
50baf1a… lmata 294 }
50baf1a… lmata 295 print
50baf1a… lmata 296 }
50baf1a… lmata 297 END {
50baf1a… lmata 298 if (!features_seen) {
50baf1a… lmata 299 if (NR > 0) {
50baf1a… lmata 300 print ""
50baf1a… lmata 301 }
50baf1a… lmata 302 print "[features]"
50baf1a… lmata 303 print "codex_hooks = true"
50baf1a… lmata 304 } else if (in_features && !codex_hooks_set) {
50baf1a… lmata 305 print "codex_hooks = true"
50baf1a… lmata 306 }
50baf1a… lmata 307 }
50baf1a… lmata 308 ' "$file" > "$tmp"
50baf1a… lmata 309 mv "$tmp" "$file"
50baf1a… lmata 310 }
50baf1a… lmata 311
50baf1a… lmata 312 need_cmd go
50baf1a… lmata 313 need_cmd jq
50baf1a… lmata 314
50baf1a… lmata 315 POST_CMD="$HOOKS_DIR/scuttlebot-post.sh"
50baf1a… lmata 316 CHECK_CMD="$HOOKS_DIR/scuttlebot-check.sh"
50baf1a… lmata 317 LAUNCHER_DST="$BIN_DIR/codex-relay"
50baf1a… lmata 318
50baf1a… lmata 319 mkdir -p "$HOOKS_DIR" "$BIN_DIR"
50baf1a… lmata 320 ensure_parent_dir "$HOOKS_JSON"
50baf1a… lmata 321 ensure_parent_dir "$CODEX_CONFIG"
50baf1a… lmata 322 ensure_parent_dir "$CONFIG_FILE"
50baf1a… lmata 323
50baf1a… lmata 324 backup_file "$POST_CMD"
50baf1a… lmata 325 backup_file "$CHECK_CMD"
50baf1a… lmata 326 backup_file "$LAUNCHER_DST"
50baf1a… lmata 327 install -m 0755 "$REPO_ROOT/skills/openai-relay/hooks/scuttlebot-post.sh" "$POST_CMD"
50baf1a… lmata 328 install -m 0755 "$REPO_ROOT/skills/openai-relay/hooks/scuttlebot-check.sh" "$CHECK_CMD"
50baf1a… lmata 329 (cd "$REPO_ROOT" && go build -o "$LAUNCHER_DST" ./cmd/codex-relay)
50baf1a… lmata 330
50baf1a… lmata 331 backup_file "$HOOKS_JSON"
50baf1a… lmata 332 if [ -f "$HOOKS_JSON" ]; then
50baf1a… lmata 333 jq --arg pre_matcher "Bash|Edit|Write" \
50baf1a… lmata 334 --arg pre_cmd "$CHECK_CMD" \
50baf1a… lmata 335 --arg post_matcher "Bash|Read|Edit|Write|Glob|Grep|Agent" \
50baf1a… lmata 336 --arg post_cmd "$POST_CMD" '
50baf1a… lmata 337 def ensure_command(matcher; cmd):
50baf1a… lmata 338 .hooks = (.hooks // {})
50baf1a… lmata 339 | .hooks[matcher] = (.hooks[matcher] // [])
50baf1a… lmata 340 | if any(.hooks[matcher][]?; .type == "command" and .command == cmd) then
50baf1a… lmata 341 .
50baf1a… lmata 342 else
50baf1a… lmata 343 .hooks[matcher] += [{"type":"command","command":cmd}]
50baf1a… lmata 344 end;
50baf1a… lmata 345 def ensure_matcher_entry(section; matcher; cmd):
50baf1a… lmata 346 .hooks = (.hooks // {})
50baf1a… lmata 347 | .hooks[section] = (.hooks[section] // [])
50baf1a… lmata 348 | if any(.hooks[section][]?; .matcher == matcher) then
50baf1a… lmata 349 .hooks[section] |= map(
50baf1a… lmata 350 if .matcher == matcher then
50baf1a… lmata 351 (.hooks = (.hooks // []))
50baf1a… lmata 352 | if any(.hooks[]?; .type == "command" and .command == cmd) then . else .hooks += [{"type":"command","command":cmd}] end
50baf1a… lmata 353 else
50baf1a… lmata 354 .
50baf1a… lmata 355 end
50baf1a… lmata 356 )
50baf1a… lmata 357 else
50baf1a… lmata 358 .hooks[section] += [{"matcher":matcher,"hooks":[{"type":"command","command":cmd}]}]
50baf1a… lmata 359 end;
50baf1a… lmata 360 ensure_matcher_entry("pre-tool-use"; $pre_matcher; $pre_cmd)
50baf1a… lmata 361 | ensure_matcher_entry("post-tool-use"; $post_matcher; $post_cmd)
50baf1a… lmata 362 ' "$HOOKS_JSON" > "${HOOKS_JSON}.tmp"
50baf1a… lmata 363 else
50baf1a… lmata 364 jq -n \
50baf1a… lmata 365 --arg pre_cmd "$CHECK_CMD" \
50baf1a… lmata 366 --arg post_cmd "$POST_CMD" '
50baf1a… lmata 367 {
50baf1a… lmata 368 hooks: {
50baf1a… lmata 369 "pre-tool-use": [
50baf1a… lmata 370 {
50baf1a… lmata 371 matcher: "Bash|Edit|Write",
50baf1a… lmata 372 hooks: [{type: "command", command: $pre_cmd}]
50baf1a… lmata 373 }
50baf1a… lmata 374 ],
50baf1a… lmata 375 "post-tool-use": [
50baf1a… lmata 376 {
50baf1a… lmata 377 matcher: "Bash|Read|Edit|Write|Glob|Grep|Agent",
50baf1a… lmata 378 hooks: [{type: "command", command: $post_cmd}]
50baf1a… lmata 379 }
50baf1a… lmata 380 ]
50baf1a… lmata 381 }
50baf1a… lmata 382 }
50baf1a… lmata 383 ' > "${HOOKS_JSON}.tmp"
50baf1a… lmata 384 fi
50baf1a… lmata 385 mv "${HOOKS_JSON}.tmp" "$HOOKS_JSON"
50baf1a… lmata 386
50baf1a… lmata 387 backup_file "$CODEX_CONFIG"
50baf1a… lmata 388 ensure_codex_hooks_feature "$CODEX_CONFIG"
50baf1a… lmata 389
50baf1a… lmata 390 backup_file "$CONFIG_FILE"
50baf1a… lmata 391 if [ ! -f "$CONFIG_FILE" ]; then
50baf1a… lmata 392 : > "$CONFIG_FILE"
50baf1a… lmata 393 fi
50baf1a… lmata 394 if [ -n "$SCUTTLEBOT_URL_VALUE" ]; then
50baf1a… lmata 395 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_URL "$SCUTTLEBOT_URL_VALUE"
50baf1a… lmata 396 fi
50baf1a… lmata 397 if [ -n "$SCUTTLEBOT_TOKEN_VALUE" ]; then
50baf1a… lmata 398 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TOKEN "$SCUTTLEBOT_TOKEN_VALUE"
50baf1a… lmata 399 fi
50baf1a… lmata 400 if [ -n "$SCUTTLEBOT_CHANNEL_VALUE" ]; then
50baf1a… lmata 401 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNEL "${SCUTTLEBOT_CHANNEL_VALUE#\#}"
1d3caa2… lmata 402 fi
1d3caa2… lmata 403 if [ -n "$SCUTTLEBOT_CHANNELS_VALUE" ]; then
1d3caa2… lmata 404 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_CHANNELS "$SCUTTLEBOT_CHANNELS_VALUE"
b8ce843… lmata 405 fi
24a217e… lmata 406 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_TRANSPORT "$SCUTTLEBOT_TRANSPORT_VALUE"
24a217e… lmata 407 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_ADDR "$SCUTTLEBOT_IRC_ADDR_VALUE"
b8ce843… lmata 408 if [ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ]; then
24a217e… lmata 409 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS "$SCUTTLEBOT_IRC_PASS_VALUE"
b8ce843… lmata 410 else
b8ce843… lmata 411 remove_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_PASS
24a217e… lmata 412 fi
b8ce843… lmata 413 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_IRC_DELETE_ON_CLOSE "$SCUTTLEBOT_IRC_DELETE_ON_CLOSE_VALUE"
50baf1a… lmata 414 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_HOOKS_ENABLED "$SCUTTLEBOT_HOOKS_ENABLED_VALUE"
50baf1a… lmata 415 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_INTERRUPT_ON_MESSAGE "$SCUTTLEBOT_INTERRUPT_ON_MESSAGE_VALUE"
50baf1a… lmata 416 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_POLL_INTERVAL "$SCUTTLEBOT_POLL_INTERVAL_VALUE"
24a217e… lmata 417 upsert_env_var "$CONFIG_FILE" SCUTTLEBOT_PRESENCE_HEARTBEAT "$SCUTTLEBOT_PRESENCE_HEARTBEAT_VALUE"
50baf1a… lmata 418
50baf1a… lmata 419 printf 'Installed Codex relay files:\n'
50baf1a… lmata 420 printf ' hooks: %s\n' "$HOOKS_DIR"
50baf1a… lmata 421 printf ' hooks.json: %s\n' "$HOOKS_JSON"
50baf1a… lmata 422 printf ' config: %s\n' "$CODEX_CONFIG"
50baf1a… lmata 423 printf ' broker: %s\n' "$LAUNCHER_DST"
50baf1a… lmata 424 printf ' env: %s\n' "$CONFIG_FILE"
b8ce843… lmata 425 printf ' irc auth: %s\n' "$([ "$SCUTTLEBOT_IRC_PASS_MODE" = "fixed" ] && printf 'fixed-pass override' || printf 'auto-register')"
50baf1a… lmata 426 printf '\n'
50baf1a… lmata 427 printf 'Next steps:\n'
50baf1a… lmata 428 printf ' 1. Launch with: %s\n' "$LAUNCHER_DST"
50baf1a… lmata 429 printf ' 2. Watch IRC for: codex-{repo}-{session}\n'
50baf1a… lmata 430 printf ' 3. Mention that nick to interrupt before the next action\n'
50baf1a… lmata 431 printf '\n'
50baf1a… lmata 432 printf 'Disable without uninstalling:\n'
50baf1a… lmata 433 printf ' SCUTTLEBOT_HOOKS_ENABLED=0 %s\n' "$LAUNCHER_DST"

Keyboard Shortcuts

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