ScuttleBot

chore: dev tooling cleanup — remove LaunchAgent references from run.sh, update bootstrap and config

lmata 2026-04-03 00:13 trunk
Commit 10b6d9298a012462ba857d8ba402e7e129053f77d7a717df500daffbd8a6e670
+10 -4
--- Makefile
+++ Makefile
@@ -1,13 +1,19 @@
11
.PHONY: all build fmt vet lint test test-smoke clean install \
2
- install-claude-relay install-codex-relay install-gemini-relay
2
+ install-claude-relay install-codex-relay install-gemini-relay \
3
+ chatbots
34
45
BINS := bin/scuttlebot bin/scuttlectl bin/claude-relay bin/codex-relay \
5
- bin/gemini-relay bin/claude-agent bin/codex-agent bin/gemini-agent \
6
- bin/fleet-cmd
6
+ bin/gemini-relay bin/fleet-cmd
7
+
8
+CHATBOT_BINS := bin/claude-agent bin/codex-agent bin/gemini-agent
79
810
all: $(BINS)
11
+
12
+# chatbots builds the optional IRC chatbot agents (claude-agent, codex-agent,
13
+# gemini-agent). These are not part of the default build — see docs/chatbot-agents.md.
14
+chatbots: $(CHATBOT_BINS)
915
1016
build:
1117
go build ./...
1218
1319
fmt:
@@ -28,11 +34,11 @@
2834
# Install daemon + CLI to $(GOPATH)/bin (or ~/go/bin).
2935
install:
3036
go install ./cmd/scuttlebot ./cmd/scuttlectl
3137
3238
clean:
33
- rm -f $(BINS)
39
+ rm -f $(BINS) $(CHATBOT_BINS)
3440
3541
# --- relay install helpers ---
3642
3743
install-claude-relay:
3844
bash skills/scuttlebot-relay/scripts/install-claude-relay.sh
3945
--- Makefile
+++ Makefile
@@ -1,13 +1,19 @@
1 .PHONY: all build fmt vet lint test test-smoke clean install \
2 install-claude-relay install-codex-relay install-gemini-relay
 
3
4 BINS := bin/scuttlebot bin/scuttlectl bin/claude-relay bin/codex-relay \
5 bin/gemini-relay bin/claude-agent bin/codex-agent bin/gemini-agent \
6 bin/fleet-cmd
 
7
8 all: $(BINS)
 
 
 
 
9
10 build:
11 go build ./...
12
13 fmt:
@@ -28,11 +34,11 @@
28 # Install daemon + CLI to $(GOPATH)/bin (or ~/go/bin).
29 install:
30 go install ./cmd/scuttlebot ./cmd/scuttlectl
31
32 clean:
33 rm -f $(BINS)
34
35 # --- relay install helpers ---
36
37 install-claude-relay:
38 bash skills/scuttlebot-relay/scripts/install-claude-relay.sh
39
--- Makefile
+++ Makefile
@@ -1,13 +1,19 @@
1 .PHONY: all build fmt vet lint test test-smoke clean install \
2 install-claude-relay install-codex-relay install-gemini-relay \
3 chatbots
4
5 BINS := bin/scuttlebot bin/scuttlectl bin/claude-relay bin/codex-relay \
6 bin/gemini-relay bin/fleet-cmd
7
8 CHATBOT_BINS := bin/claude-agent bin/codex-agent bin/gemini-agent
9
10 all: $(BINS)
11
12 # chatbots builds the optional IRC chatbot agents (claude-agent, codex-agent,
13 # gemini-agent). These are not part of the default build — see docs/chatbot-agents.md.
14 chatbots: $(CHATBOT_BINS)
15
16 build:
17 go build ./...
18
19 fmt:
@@ -28,11 +34,11 @@
34 # Install daemon + CLI to $(GOPATH)/bin (or ~/go/bin).
35 install:
36 go install ./cmd/scuttlebot ./cmd/scuttlectl
37
38 clean:
39 rm -f $(BINS) $(CHATBOT_BINS)
40
41 # --- relay install helpers ---
42
43 install-claude-relay:
44 bash skills/scuttlebot-relay/scripts/install-claude-relay.sh
45
+35
--- bootstrap.md
+++ bootstrap.md
@@ -323,5 +323,40 @@
323323
scuttlectl admin remove alice # remove admin
324324
325325
# Docker
326326
docker compose -f deploy/compose/docker-compose.yml up
327327
```
328
+
329
+## Optional: IRC Chatbot Agents
330
+
331
+`cmd/claude-agent`, `cmd/codex-agent`, and `cmd/gemini-agent` are standalone IRC bots that connect to a channel and respond to prompts using an LLM backend. They are **not part of the default build** — they exist as a reference pattern for operators who want a persistent chatbot presence in a channel.
332
+
333
+These are distinct from the relay brokers (`claude-relay`, `codex-relay`, `gemini-relay`). The difference:
334
+
335
+| | Chatbot agent | Relay broker |
336
+|---|---|---|
337
+| Wraps a coding CLI | No | Yes |
338
+| Reads/writes files, runs commands | No | Yes (via the CLI) |
339
+| Always-on, responds to any mention | Yes | No — tied to an active session |
340
+| Useful for fleet coordination | Novelty only | Core pattern |
341
+
342
+The relay broker is the right tool for agent work. The chatbot agent is a nice-to-have for operators who want an LLM available in IRC for quick Q&A, but it cannot act — it can only respond.
343
+
344
+### Running one
345
+
346
+```bash
347
+# Build (not included in make all)
348
+make chatbots
349
+
350
+# Register a nick in scuttlebot
351
+TOKEN=$(./run.sh token)
352
+curl -s -X POST -H "Authorization: Bearer $TOKEN" \
353
+ -H "Content-Type: application/json" \
354
+ -d '{"nick":"claude","type":"worker","channels":["#general"]}' \
355
+ http://localhost:8080/v1/agents/register
356
+
357
+# Connect (use the passphrase from the register response)
358
+bin/claude-agent --irc 127.0.0.1:6667 --nick claude --pass <passphrase> \
359
+ --api-url http://localhost:8080 --token $TOKEN --backend anthro
360
+```
361
+
362
+Swap `claude-agent` → `codex-agent` (backend `openai`) or `gemini-agent` (backend `gemini`) for other providers. All three accept the same flags.
328363
--- bootstrap.md
+++ bootstrap.md
@@ -323,5 +323,40 @@
323 scuttlectl admin remove alice # remove admin
324
325 # Docker
326 docker compose -f deploy/compose/docker-compose.yml up
327 ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
--- bootstrap.md
+++ bootstrap.md
@@ -323,5 +323,40 @@
323 scuttlectl admin remove alice # remove admin
324
325 # Docker
326 docker compose -f deploy/compose/docker-compose.yml up
327 ```
328
329 ## Optional: IRC Chatbot Agents
330
331 `cmd/claude-agent`, `cmd/codex-agent`, and `cmd/gemini-agent` are standalone IRC bots that connect to a channel and respond to prompts using an LLM backend. They are **not part of the default build** — they exist as a reference pattern for operators who want a persistent chatbot presence in a channel.
332
333 These are distinct from the relay brokers (`claude-relay`, `codex-relay`, `gemini-relay`). The difference:
334
335 | | Chatbot agent | Relay broker |
336 |---|---|---|
337 | Wraps a coding CLI | No | Yes |
338 | Reads/writes files, runs commands | No | Yes (via the CLI) |
339 | Always-on, responds to any mention | Yes | No — tied to an active session |
340 | Useful for fleet coordination | Novelty only | Core pattern |
341
342 The relay broker is the right tool for agent work. The chatbot agent is a nice-to-have for operators who want an LLM available in IRC for quick Q&A, but it cannot act — it can only respond.
343
344 ### Running one
345
346 ```bash
347 # Build (not included in make all)
348 make chatbots
349
350 # Register a nick in scuttlebot
351 TOKEN=$(./run.sh token)
352 curl -s -X POST -H "Authorization: Bearer $TOKEN" \
353 -H "Content-Type: application/json" \
354 -d '{"nick":"claude","type":"worker","channels":["#general"]}' \
355 http://localhost:8080/v1/agents/register
356
357 # Connect (use the passphrase from the register response)
358 bin/claude-agent --irc 127.0.0.1:6667 --nick claude --pass <passphrase> \
359 --api-url http://localhost:8080 --token $TOKEN --backend anthro
360 ```
361
362 Swap `claude-agent` → `codex-agent` (backend `openai`) or `gemini-agent` (backend `gemini`) for other providers. All three accept the same flags.
363
+9 -9
--- calliope.md
+++ calliope.md
@@ -1,20 +1,20 @@
11
# Calliope — scuttlebot
22
<!-- Agent shim for https://github.com/calliopeai/calliope-cli -->
33
44
Primary conventions doc: [`bootstrap.md`](bootstrap.md)
5
-Context seed: [`memory.md`](memory.md)
65
7
-Read both before writing any code.
6
+Read it before writing any code.
87
98
---
109
1110
## Project-specific notes
1211
13
-- Language: Python 3.12+
14
-- Transport: IRC — all agent coordination flows through IRC channels and messages
15
-- Async runtime: asyncio throughout; IRC library TBD (irc3 or similar)
16
-- No web layer, no database — pure message-passing over IRC
12
+- Language: Go 1.22+
13
+- Transport: IRC — all agent coordination flows through Ergo IRC channels and messages
14
+- HTTP API: `internal/api/` — Bearer token auth, JSON, serves the web UI at `/ui/`
15
+- No ORM, no database — state persisted as YAML/JSON files
1716
- Human observable by design: everything an agent does is visible in IRC
18
-- Test runner: pytest + pytest-asyncio
19
-- Formatter/linter: Ruff (replaces black, flake8, isort)
20
-- Package manager: uv (`uv sync`, `uv run pytest`)
17
+- Test runner: `go test ./...`
18
+- Formatter: `gofmt` (enforced)
19
+- Linter: `golangci-lint run`
20
+- Dev helper: `./run.sh` (start / stop / restart / token / log / test / e2e / clean)
2121
--- calliope.md
+++ calliope.md
@@ -1,20 +1,20 @@
1 # Calliope — scuttlebot
2 <!-- Agent shim for https://github.com/calliopeai/calliope-cli -->
3
4 Primary conventions doc: [`bootstrap.md`](bootstrap.md)
5 Context seed: [`memory.md`](memory.md)
6
7 Read both before writing any code.
8
9 ---
10
11 ## Project-specific notes
12
13 - Language: Python 3.12+
14 - Transport: IRC — all agent coordination flows through IRC channels and messages
15 - Async runtime: asyncio throughout; IRC library TBD (irc3 or similar)
16 - No web layer, no database — pure message-passing over IRC
17 - Human observable by design: everything an agent does is visible in IRC
18 - Test runner: pytest + pytest-asyncio
19 - Formatter/linter: Ruff (replaces black, flake8, isort)
20 - Package manager: uv (`uv sync`, `uv run pytest`)
 
21
--- calliope.md
+++ calliope.md
@@ -1,20 +1,20 @@
1 # Calliope — scuttlebot
2 <!-- Agent shim for https://github.com/calliopeai/calliope-cli -->
3
4 Primary conventions doc: [`bootstrap.md`](bootstrap.md)
 
5
6 Read it before writing any code.
7
8 ---
9
10 ## Project-specific notes
11
12 - Language: Go 1.22+
13 - Transport: IRC — all agent coordination flows through Ergo IRC channels and messages
14 - HTTP API: `internal/api/` — Bearer token auth, JSON, serves the web UI at `/ui/`
15 - No ORM, no database — state persisted as YAML/JSON files
16 - Human observable by design: everything an agent does is visible in IRC
17 - Test runner: `go test ./...`
18 - Formatter: `gofmt` (enforced)
19 - Linter: `golangci-lint run`
20 - Dev helper: `./run.sh` (start / stop / restart / token / log / test / e2e / clean)
21
M run.sh
+1 -83
--- run.sh
+++ run.sh
@@ -2,30 +2,23 @@
22
# run.sh — scuttlebot dev helper
33
# Usage: ./run.sh [command]
44
# (no args) build and start scuttlebot
55
# stop kill running scuttlebot
66
# restart stop + build + start
7
-# agent build and run a claude IRC agent with a fleet-style nick
87
# token print the current API token
98
# log tail the log (if logging to file is configured)
109
# test run Go unit tests
1110
# e2e run Playwright e2e tests (requires scuttlebot running)
1211
# clean remove built binaries
13
-#
14
-# After start/restart, if ~/Library/LaunchAgents/io.conflict.claude-agent.plist
15
-# exists, the claude IRC agent credentials are rotated and the LaunchAgent reloaded.
1612
1713
set -euo pipefail
1814
1915
BINARY=bin/scuttlebot
2016
CONFIG=${SCUTTLEBOT_CONFIG:-scuttlebot.yaml}
2117
TOKEN_FILE=data/ergo/api_token
2218
PID_FILE=.scuttlebot.pid
2319
LOG_FILE=.scuttlebot.log
24
-CLAUDE_AGENT_ENV="${CLAUDE_AGENT_ENV:-$HOME/.config/scuttlebot-claude-agent.env}"
25
-CLAUDE_AGENT_PLIST="${CLAUDE_AGENT_PLIST:-$HOME/Library/LaunchAgents/io.conflict.claude-agent.plist}"
26
-
2720
cmd=${1:-start}
2821
2922
_pid() { cat "$PID_FILE" 2>/dev/null || echo ""; }
3023
3124
_running() {
@@ -86,102 +79,27 @@
8679
echo "no token file found (is scuttlebot running?)" >&2
8780
exit 1
8881
fi
8982
}
9083
91
-# _sync_claude_agent rotates the claude IRC agent's credentials, updates the
92
-# env file, and reloads the LaunchAgent. No-ops silently if the plist or env
93
-# file don't exist (agent not installed on this machine).
94
-_sync_claude_agent() {
95
- [[ -f "$CLAUDE_AGENT_PLIST" ]] || return 0
96
- [[ -f "$CLAUDE_AGENT_ENV" ]] || return 0
97
-
98
- local token; token=$(_token 2>/dev/null) || return 0
99
-
100
- # Wait up to 15s for the HTTP API, then give ergo another 5s to finish
101
- # starting NickServ before we attempt a password rotation.
102
- local ready=0
103
- for i in $(seq 1 15); do
104
- curl -sf -H "Authorization: Bearer $token" "http://localhost:8080/v1/status" >/dev/null 2>&1 && ready=1 && break
105
- sleep 1
106
- done
107
- [[ $ready -eq 1 ]] || { echo "warning: scuttlebot API not ready, skipping claude-agent sync" >&2; return 0; }
108
- sleep 5
109
-
110
- echo "syncing claude-agent credentials..."
111
- local resp; resp=$(curl -sf -X POST \
112
- -H "Authorization: Bearer $token" \
113
- "http://localhost:8080/v1/agents/claude/rotate" 2>/dev/null) || {
114
- echo "warning: could not rotate claude-agent credentials (API not ready?)" >&2
115
- return 0
116
- }
117
-
118
- local pass; pass=$(echo "$resp" | grep -o '"passphrase":"[^"]*"' | cut -d'"' -f4)
119
- [[ -n "$pass" ]] || { echo "warning: empty passphrase in rotate response" >&2; return 0; }
120
-
121
- # Rewrite only the CLAUDE_AGENT_PASS line; preserve everything else.
122
- sed -i '' "s|^CLAUDE_AGENT_PASS=.*|CLAUDE_AGENT_PASS=$pass|" "$CLAUDE_AGENT_ENV"
123
-
124
- launchctl unload "$CLAUDE_AGENT_PLIST" 2>/dev/null || true
125
- launchctl load "$CLAUDE_AGENT_PLIST"
126
- echo "claude-agent reloaded"
127
-}
128
-
129
-_run_agent() {
130
- local token; token=$(_token)
131
- local base; base=$(basename "$(pwd)" | tr -cs '[:alnum:]_-' '-' | tr '[:upper:]' '[:lower:]')
132
- local session; session=$(printf '%s' "$$|$PPID|$(date +%s)" | cksum | awk '{printf "%08x\n", $1}')
133
- local nick="claude-${base}-${session}"
134
-
135
- echo "registering agent nick: $nick"
136
- local resp; resp=$(curl -sf -X POST \
137
- -H "Authorization: Bearer $token" \
138
- -H "Content-Type: application/json" \
139
- -d "{\"nick\":\"$nick\",\"type\":\"worker\",\"channels\":[\"#general\"]}" \
140
- "http://localhost:8080/v1/agents/register")
141
- local pass; pass=$(echo "$resp" | grep -o '"passphrase":"[^"]*"' | cut -d'"' -f4)
142
- [[ -n "$pass" ]] || { echo "error: failed to register agent" >&2; exit 1; }
143
-
144
- # Clean up registration on exit.
145
- trap 'echo "removing agent $nick..."; curl -sf -X DELETE \
146
- -H "Authorization: Bearer '"$token"'" \
147
- "http://localhost:8080/v1/agents/$nick" >/dev/null || true' EXIT INT TERM
148
-
149
- echo "connecting as $nick..."
150
- local backend="${SCUTTLEBOT_BACKEND:-anthro}"
151
- bin/claude-agent \
152
- --irc 127.0.0.1:6667 \
153
- --nick "$nick" \
154
- --pass "$pass" \
155
- --channels "#general" \
156
- --api-url "http://localhost:8080" \
157
- --token "$token" \
158
- --backend "$backend"
159
-}
16084
16185
case "$cmd" in
16286
start)
16387
_build
16488
_start
165
- _sync_claude_agent
16689
;;
16790
stop)
16891
_stop
16992
;;
17093
restart)
17194
_stop || true
17295
_build
17396
_start
174
- _sync_claude_agent
17597
;;
17698
build)
17799
_build
178100
;;
179
- agent)
180
- go build -o bin/claude-agent ./cmd/claude-agent
181
- _run_agent "${@:2}"
182
- ;;
183101
token)
184102
_token
185103
;;
186104
log|logs)
187105
tail -f "$LOG_FILE"
@@ -199,9 +117,9 @@
199117
_stop || true
200118
rm -f "$BINARY" bin/scuttlectl "$LOG_FILE" "$PID_FILE"
201119
echo "clean"
202120
;;
203121
*)
204
- echo "usage: $0 {start|stop|restart|agent|build|token|log|test|e2e|clean}"
122
+ echo "usage: $0 {start|stop|restart|build|token|log|test|e2e|clean}"
205123
exit 1
206124
;;
207125
esac
208126
--- run.sh
+++ run.sh
@@ -2,30 +2,23 @@
2 # run.sh — scuttlebot dev helper
3 # Usage: ./run.sh [command]
4 # (no args) build and start scuttlebot
5 # stop kill running scuttlebot
6 # restart stop + build + start
7 # agent build and run a claude IRC agent with a fleet-style nick
8 # token print the current API token
9 # log tail the log (if logging to file is configured)
10 # test run Go unit tests
11 # e2e run Playwright e2e tests (requires scuttlebot running)
12 # clean remove built binaries
13 #
14 # After start/restart, if ~/Library/LaunchAgents/io.conflict.claude-agent.plist
15 # exists, the claude IRC agent credentials are rotated and the LaunchAgent reloaded.
16
17 set -euo pipefail
18
19 BINARY=bin/scuttlebot
20 CONFIG=${SCUTTLEBOT_CONFIG:-scuttlebot.yaml}
21 TOKEN_FILE=data/ergo/api_token
22 PID_FILE=.scuttlebot.pid
23 LOG_FILE=.scuttlebot.log
24 CLAUDE_AGENT_ENV="${CLAUDE_AGENT_ENV:-$HOME/.config/scuttlebot-claude-agent.env}"
25 CLAUDE_AGENT_PLIST="${CLAUDE_AGENT_PLIST:-$HOME/Library/LaunchAgents/io.conflict.claude-agent.plist}"
26
27 cmd=${1:-start}
28
29 _pid() { cat "$PID_FILE" 2>/dev/null || echo ""; }
30
31 _running() {
@@ -86,102 +79,27 @@
86 echo "no token file found (is scuttlebot running?)" >&2
87 exit 1
88 fi
89 }
90
91 # _sync_claude_agent rotates the claude IRC agent's credentials, updates the
92 # env file, and reloads the LaunchAgent. No-ops silently if the plist or env
93 # file don't exist (agent not installed on this machine).
94 _sync_claude_agent() {
95 [[ -f "$CLAUDE_AGENT_PLIST" ]] || return 0
96 [[ -f "$CLAUDE_AGENT_ENV" ]] || return 0
97
98 local token; token=$(_token 2>/dev/null) || return 0
99
100 # Wait up to 15s for the HTTP API, then give ergo another 5s to finish
101 # starting NickServ before we attempt a password rotation.
102 local ready=0
103 for i in $(seq 1 15); do
104 curl -sf -H "Authorization: Bearer $token" "http://localhost:8080/v1/status" >/dev/null 2>&1 && ready=1 && break
105 sleep 1
106 done
107 [[ $ready -eq 1 ]] || { echo "warning: scuttlebot API not ready, skipping claude-agent sync" >&2; return 0; }
108 sleep 5
109
110 echo "syncing claude-agent credentials..."
111 local resp; resp=$(curl -sf -X POST \
112 -H "Authorization: Bearer $token" \
113 "http://localhost:8080/v1/agents/claude/rotate" 2>/dev/null) || {
114 echo "warning: could not rotate claude-agent credentials (API not ready?)" >&2
115 return 0
116 }
117
118 local pass; pass=$(echo "$resp" | grep -o '"passphrase":"[^"]*"' | cut -d'"' -f4)
119 [[ -n "$pass" ]] || { echo "warning: empty passphrase in rotate response" >&2; return 0; }
120
121 # Rewrite only the CLAUDE_AGENT_PASS line; preserve everything else.
122 sed -i '' "s|^CLAUDE_AGENT_PASS=.*|CLAUDE_AGENT_PASS=$pass|" "$CLAUDE_AGENT_ENV"
123
124 launchctl unload "$CLAUDE_AGENT_PLIST" 2>/dev/null || true
125 launchctl load "$CLAUDE_AGENT_PLIST"
126 echo "claude-agent reloaded"
127 }
128
129 _run_agent() {
130 local token; token=$(_token)
131 local base; base=$(basename "$(pwd)" | tr -cs '[:alnum:]_-' '-' | tr '[:upper:]' '[:lower:]')
132 local session; session=$(printf '%s' "$$|$PPID|$(date +%s)" | cksum | awk '{printf "%08x\n", $1}')
133 local nick="claude-${base}-${session}"
134
135 echo "registering agent nick: $nick"
136 local resp; resp=$(curl -sf -X POST \
137 -H "Authorization: Bearer $token" \
138 -H "Content-Type: application/json" \
139 -d "{\"nick\":\"$nick\",\"type\":\"worker\",\"channels\":[\"#general\"]}" \
140 "http://localhost:8080/v1/agents/register")
141 local pass; pass=$(echo "$resp" | grep -o '"passphrase":"[^"]*"' | cut -d'"' -f4)
142 [[ -n "$pass" ]] || { echo "error: failed to register agent" >&2; exit 1; }
143
144 # Clean up registration on exit.
145 trap 'echo "removing agent $nick..."; curl -sf -X DELETE \
146 -H "Authorization: Bearer '"$token"'" \
147 "http://localhost:8080/v1/agents/$nick" >/dev/null || true' EXIT INT TERM
148
149 echo "connecting as $nick..."
150 local backend="${SCUTTLEBOT_BACKEND:-anthro}"
151 bin/claude-agent \
152 --irc 127.0.0.1:6667 \
153 --nick "$nick" \
154 --pass "$pass" \
155 --channels "#general" \
156 --api-url "http://localhost:8080" \
157 --token "$token" \
158 --backend "$backend"
159 }
160
161 case "$cmd" in
162 start)
163 _build
164 _start
165 _sync_claude_agent
166 ;;
167 stop)
168 _stop
169 ;;
170 restart)
171 _stop || true
172 _build
173 _start
174 _sync_claude_agent
175 ;;
176 build)
177 _build
178 ;;
179 agent)
180 go build -o bin/claude-agent ./cmd/claude-agent
181 _run_agent "${@:2}"
182 ;;
183 token)
184 _token
185 ;;
186 log|logs)
187 tail -f "$LOG_FILE"
@@ -199,9 +117,9 @@
199 _stop || true
200 rm -f "$BINARY" bin/scuttlectl "$LOG_FILE" "$PID_FILE"
201 echo "clean"
202 ;;
203 *)
204 echo "usage: $0 {start|stop|restart|agent|build|token|log|test|e2e|clean}"
205 exit 1
206 ;;
207 esac
208
--- run.sh
+++ run.sh
@@ -2,30 +2,23 @@
2 # run.sh — scuttlebot dev helper
3 # Usage: ./run.sh [command]
4 # (no args) build and start scuttlebot
5 # stop kill running scuttlebot
6 # restart stop + build + start
 
7 # token print the current API token
8 # log tail the log (if logging to file is configured)
9 # test run Go unit tests
10 # e2e run Playwright e2e tests (requires scuttlebot running)
11 # clean remove built binaries
 
 
 
12
13 set -euo pipefail
14
15 BINARY=bin/scuttlebot
16 CONFIG=${SCUTTLEBOT_CONFIG:-scuttlebot.yaml}
17 TOKEN_FILE=data/ergo/api_token
18 PID_FILE=.scuttlebot.pid
19 LOG_FILE=.scuttlebot.log
 
 
 
20 cmd=${1:-start}
21
22 _pid() { cat "$PID_FILE" 2>/dev/null || echo ""; }
23
24 _running() {
@@ -86,102 +79,27 @@
79 echo "no token file found (is scuttlebot running?)" >&2
80 exit 1
81 fi
82 }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
85 case "$cmd" in
86 start)
87 _build
88 _start
 
89 ;;
90 stop)
91 _stop
92 ;;
93 restart)
94 _stop || true
95 _build
96 _start
 
97 ;;
98 build)
99 _build
100 ;;
 
 
 
 
101 token)
102 _token
103 ;;
104 log|logs)
105 tail -f "$LOG_FILE"
@@ -199,9 +117,9 @@
117 _stop || true
118 rm -f "$BINARY" bin/scuttlectl "$LOG_FILE" "$PID_FILE"
119 echo "clean"
120 ;;
121 *)
122 echo "usage: $0 {start|stop|restart|build|token|log|test|e2e|clean}"
123 exit 1
124 ;;
125 esac
126
+59 -75
--- scuttlebot.yaml
+++ scuttlebot.yaml
@@ -1,78 +1,62 @@
1
-# scuttlebot.yaml — example standalone config.
2
-# Copy to scuttlebot.yaml and edit. All fields are optional; defaults shown.
3
-
41
ergo:
5
- # binary_path: ergo # path to ergo binary; auto-downloaded if not found
6
- # data_dir: ./data/ergo # where ergo stores ircd.db and generated config
7
- # network_name: scuttlebot # IRC network name
8
- # server_name: irc.scuttlebot.local
9
- # irc_addr: 127.0.0.1:6667 # IRC listen address
10
- # api_addr: 127.0.0.1:8089 # ergo HTTP API address
11
- # api_token: "" # auto-generated if blank
12
- history:
13
- # enabled: false
14
- # postgres_dsn: postgres://user:pass@localhost/scuttlebot?sslmode=disable
15
-
2
+ external: false
3
+ binary_path: /Users/ragelink/repos/conflict/scuttlebot/data/ergo/ergo
4
+ data_dir: ./data/ergo
5
+ network_name: scuttlebot
6
+ server_name: irc.scuttlebot.local
7
+ irc_addr: 127.0.0.1:6667
8
+ api_addr: 127.0.0.1:8089
9
+ api_token: 40f721538f6720ddca1ee02c7e58fee8f75b4d46287fb5bd
10
+ history:
11
+ enabled: false
12
+ postgres_dsn: ""
13
+ mysql:
14
+ host: ""
15
+ port: 0
16
+ user: ""
17
+ password: ""
18
+ database: ""
1619
datastore:
17
- # driver: sqlite # "sqlite" or "postgres"
18
- # dsn: ./data/scuttlebot.db
19
-
20
+ driver: sqlite
21
+ dsn: ./data/scuttlebot.db
2022
bridge:
21
- # enabled: true
22
- # nick: bridge
23
- # channels: ["#general"]
24
- # buffer_size: 200
25
- # web_user_ttl_minutes: 5 # keep HTTP bridge nicks visible in /users after their last post
26
-
27
-# api_addr: :8080 # scuttlebot REST API listen address
28
-
29
-# topology defines channel structure and autojoin policy.
30
-# Static channels are provisioned at startup; types apply to agent-created channels.
31
-# This is domain-agnostic — replace the example types with whatever fits your workflow.
32
-#
33
-# topology:
34
-# channels:
35
-# - name: "#general"
36
-# topic: "Fleet coordination"
37
-# ops: [bridge, oracle]
38
-# autojoin: [bridge, oracle, scribe, herald]
39
-# - name: "#alerts"
40
-# topic: "Alerts and incidents"
41
-# autojoin: [bridge, sentinel, steward, oracle]
42
-#
43
-# types:
44
-# # --- software development (default example) ---
45
-# - name: task
46
-# prefix: "task." # matches #task.gh-42, #task.JIRA-99, etc.
47
-# autojoin: [bridge, scribe]
48
-# supervision: "#general" # where summaries surface; agents post here too
49
-# ephemeral: true
50
-# ttl: 72h
51
-# - name: sprint
52
-# prefix: "sprint."
53
-# autojoin: [bridge, oracle, herald]
54
-# - name: feature
55
-# prefix: "feature."
56
-# autojoin: [bridge, scribe, herald]
57
-# supervision: "#general"
58
-# - name: infra
59
-# prefix: "infra."
60
-# autojoin: [bridge, sentinel, steward]
61
-# supervision: "#alerts"
62
-# - name: incident
63
-# prefix: "incident."
64
-# autojoin: [bridge, sentinel, steward, oracle, auditbot]
65
-# supervision: "#alerts"
66
-# ephemeral: true
67
-# ttl: 168h # 1 week
68
-#
69
-# # --- other domain examples (uncomment/replace as needed) ---
70
-# # - name: experiment # data science
71
-# # prefix: "experiment."
72
-# # autojoin: [bridge, scribe]
73
-# # - name: ticket # customer support
74
-# # prefix: "ticket."
75
-# # autojoin: [bridge, scribe]
76
-# # supervision: "#general"
77
-# # ephemeral: true
78
-# # ttl: 48h
23
+ enabled: true
24
+ nick: bridge
25
+ password: f7496206ad3969190cd0f7eb8accb79ec249c1b908484ae4
26
+ channels: []
27
+ buffer_size: 200
28
+ web_user_ttl_minutes: 8
29
+tls:
30
+ domain: ""
31
+ email: ""
32
+ cert_dir: ""
33
+ allow_insecure: false
34
+llm:
35
+ backends: []
36
+topology:
37
+ nick: topology
38
+ channels:
39
+ - name: '#general'
40
+ topic: Fleet coordination
41
+ ops: []
42
+ voice: []
43
+ autojoin:
44
+ - bridge
45
+ types: []
46
+config_history:
47
+ keep: 20
48
+ dir: ""
49
+agent_policy:
50
+ require_checkin: true
51
+ checkin_channel: '#fleet'
52
+ required_channels: []
53
+logging:
54
+ enabled: false
55
+ dir: ""
56
+ format: jsonl
57
+ rotation: none
58
+ max_size_mb: 0
59
+ per_channel: false
60
+ max_age_days: 0
61
+api_addr: :8080
62
+mcp_addr: :8081
7963
--- scuttlebot.yaml
+++ scuttlebot.yaml
@@ -1,78 +1,62 @@
1 # scuttlebot.yaml — example standalone config.
2 # Copy to scuttlebot.yaml and edit. All fields are optional; defaults shown.
3
4 ergo:
5 # binary_path: ergo # path to ergo binary; auto-downloaded if not found
6 # data_dir: ./data/ergo # where ergo stores ircd.db and generated config
7 # network_name: scuttlebot # IRC network name
8 # server_name: irc.scuttlebot.local
9 # irc_addr: 127.0.0.1:6667 # IRC listen address
10 # api_addr: 127.0.0.1:8089 # ergo HTTP API address
11 # api_token: "" # auto-generated if blank
12 history:
13 # enabled: false
14 # postgres_dsn: postgres://user:pass@localhost/scuttlebot?sslmode=disable
15
 
 
 
 
 
 
16 datastore:
17 # driver: sqlite # "sqlite" or "postgres"
18 # dsn: ./data/scuttlebot.db
19
20 bridge:
21 # enabled: true
22 # nick: bridge
23 # channels: ["#general"]
24 # buffer_size: 200
25 # web_user_ttl_minutes: 5 # keep HTTP bridge nicks visible in /users after their last post
26
27 # api_addr: :8080 # scuttlebot REST API listen address
28
29 # topology defines channel structure and autojoin policy.
30 # Static channels are provisioned at startup; types apply to agent-created channels.
31 # This is domain-agnostic — replace the example types with whatever fits your workflow.
32 #
33 # topology:
34 # channels:
35 # - name: "#general"
36 # topic: "Fleet coordination"
37 # ops: [bridge, oracle]
38 # autojoin: [bridge, oracle, scribe, herald]
39 # - name: "#alerts"
40 # topic: "Alerts and incidents"
41 # autojoin: [bridge, sentinel, steward, oracle]
42 #
43 # types:
44 # # --- software development (default example) ---
45 # - name: task
46 # prefix: "task." # matches #task.gh-42, #task.JIRA-99, etc.
47 # autojoin: [bridge, scribe]
48 # supervision: "#general" # where summaries surface; agents post here too
49 # ephemeral: true
50 # ttl: 72h
51 # - name: sprint
52 # prefix: "sprint."
53 # autojoin: [bridge, oracle, herald]
54 # - name: feature
55 # prefix: "feature."
56 # autojoin: [bridge, scribe, herald]
57 # supervision: "#general"
58 # - name: infra
59 # prefix: "infra."
60 # autojoin: [bridge, sentinel, steward]
61 # supervision: "#alerts"
62 # - name: incident
63 # prefix: "incident."
64 # autojoin: [bridge, sentinel, steward, oracle, auditbot]
65 # supervision: "#alerts"
66 # ephemeral: true
67 # ttl: 168h # 1 week
68 #
69 # # --- other domain examples (uncomment/replace as needed) ---
70 # # - name: experiment # data science
71 # # prefix: "experiment."
72 # # autojoin: [bridge, scribe]
73 # # - name: ticket # customer support
74 # # prefix: "ticket."
75 # # autojoin: [bridge, scribe]
76 # # supervision: "#general"
77 # # ephemeral: true
78 # # ttl: 48h
79
--- scuttlebot.yaml
+++ scuttlebot.yaml
@@ -1,78 +1,62 @@
 
 
 
1 ergo:
2 external: false
3 binary_path: /Users/ragelink/repos/conflict/scuttlebot/data/ergo/ergo
4 data_dir: ./data/ergo
5 network_name: scuttlebot
6 server_name: irc.scuttlebot.local
7 irc_addr: 127.0.0.1:6667
8 api_addr: 127.0.0.1:8089
9 api_token: 40f721538f6720ddca1ee02c7e58fee8f75b4d46287fb5bd
10 history:
11 enabled: false
12 postgres_dsn: ""
13 mysql:
14 host: ""
15 port: 0
16 user: ""
17 password: ""
18 database: ""
19 datastore:
20 driver: sqlite
21 dsn: ./data/scuttlebot.db
 
22 bridge:
23 enabled: true
24 nick: bridge
25 password: f7496206ad3969190cd0f7eb8accb79ec249c1b908484ae4
26 channels: []
27 buffer_size: 200
28 web_user_ttl_minutes: 8
29 tls:
30 domain: ""
31 email: ""
32 cert_dir: ""
33 allow_insecure: false
34 llm:
35 backends: []
36 topology:
37 nick: topology
38 channels:
39 - name: '#general'
40 topic: Fleet coordination
41 ops: []
42 voice: []
43 autojoin:
44 - bridge
45 types: []
46 config_history:
47 keep: 20
48 dir: ""
49 agent_policy:
50 require_checkin: true
51 checkin_channel: '#fleet'
52 required_channels: []
53 logging:
54 enabled: false
55 dir: ""
56 format: jsonl
57 rotation: none
58 max_size_mb: 0
59 per_channel: false
60 max_age_days: 0
61 api_addr: :8080
62 mcp_addr: :8081
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63

Keyboard Shortcuts

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