@@ -2,30 +2,23 @@
2 2 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# run.sh — scuttlebot dev helper
3 3 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# Usage: ./run.sh [command]
4 4 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# (no args) build and start scuttlebot
5 5 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# stop kill running scuttlebot
6 6 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# restart stop + build + start
7 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # agent build and run a claude IRC agent with a fleet-style nick
8 7 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# token print the current API token
9 8 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# log tail the log (if logging to file is configured)
10 9 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# test run Go unit tests
11 10 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# e2e run Playwright e2e tests (requires scuttlebot running)
12 11 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# clean remove built binaries
13 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- #
14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # After start/restart, if ~/Library/LaunchAgents/io.conflict.claude-agent.plist
15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # exists, the claude IRC agent credentials are rotated and the LaunchAgent reloaded.
16 12 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
17 13 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
set -euo pipefail
18 14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
19 15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
BINARY=bin/scuttlebot
20 16 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
CONFIG=${SCUTTLEBOT_CONFIG:-scuttlebot.yaml}
21 17 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
TOKEN_FILE=data/ergo/api_token
22 18 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PID_FILE=.scuttlebot.pid
23 19 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
LOG_FILE=.scuttlebot.log
24 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- CLAUDE_AGENT_ENV="${CLAUDE_AGENT_ENV:-$HOME/.config/scuttlebot-claude-agent.env}"
25 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- CLAUDE_AGENT_PLIST="${CLAUDE_AGENT_PLIST:-$HOME/Library/LaunchAgents/io.conflict.claude-agent.plist}"
26 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
27 20 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
cmd=${1:-start}
28 21 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
29 22 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_pid() { cat "$PID_FILE" 2>/dev/null || echo ""; }
30 23 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
31 24 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_running() {
@@ -86,102 +79,27 @@
86 79 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
echo "no token file found (is scuttlebot running?)" >&2
87 80 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
exit 1
88 81 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fi
89 82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
90 83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # _sync_claude_agent rotates the claude IRC agent's credentials, updates the
92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # env file, and reloads the LaunchAgent. No-ops silently if the plist or env
93 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # file don't exist (agent not installed on this machine).
94 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- _sync_claude_agent() {
95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- [[ -f "$CLAUDE_AGENT_PLIST" ]] || return 0
96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- [[ -f "$CLAUDE_AGENT_ENV" ]] || return 0
97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local token; token=$(_token 2>/dev/null) || return 0
99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # Wait up to 15s for the HTTP API, then give ergo another 5s to finish
101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # starting NickServ before we attempt a password rotation.
102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local ready=0
103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- for i in $(seq 1 15); do
104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- curl -sf -H "Authorization: Bearer $token" "http://localhost:8080/v1/status" >/dev/null 2>&1 && ready=1 && break
105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- sleep 1
106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- done
107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- [[ $ready -eq 1 ]] || { echo "warning: scuttlebot API not ready, skipping claude-agent sync" >&2; return 0; }
108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- sleep 5
109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- echo "syncing claude-agent credentials..."
111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local resp; resp=$(curl -sf -X POST \
112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- -H "Authorization: Bearer $token" \
113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "http://localhost:8080/v1/agents/claude/rotate" 2>/dev/null) || {
114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- echo "warning: could not rotate claude-agent credentials (API not ready?)" >&2
115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- return 0
116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local pass; pass=$(echo "$resp" | grep -o '"passphrase":"[^"]*"' | cut -d'"' -f4)
119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- [[ -n "$pass" ]] || { echo "warning: empty passphrase in rotate response" >&2; return 0; }
120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # Rewrite only the CLAUDE_AGENT_PASS line; preserve everything else.
122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- sed -i '' "s|^CLAUDE_AGENT_PASS=.*|CLAUDE_AGENT_PASS=$pass|" "$CLAUDE_AGENT_ENV"
123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- launchctl unload "$CLAUDE_AGENT_PLIST" 2>/dev/null || true
125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- launchctl load "$CLAUDE_AGENT_PLIST"
126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- echo "claude-agent reloaded"
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!
- _run_agent() {
130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local token; token=$(_token)
131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local base; base=$(basename "$(pwd)" | tr -cs '[:alnum:]_-' '-' | tr '[:upper:]' '[:lower:]')
132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local session; session=$(printf '%s' "$$|$PPID|$(date +%s)" | cksum | awk '{printf "%08x\n", $1}')
133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local nick="claude-${base}-${session}"
134 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- echo "registering agent nick: $nick"
136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local resp; resp=$(curl -sf -X POST \
137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- -H "Authorization: Bearer $token" \
138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- -H "Content-Type: application/json" \
139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- -d "{\"nick\":\"$nick\",\"type\":\"worker\",\"channels\":[\"#general\"]}" \
140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "http://localhost:8080/v1/agents/register")
141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local pass; pass=$(echo "$resp" | grep -o '"passphrase":"[^"]*"' | cut -d'"' -f4)
142 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- [[ -n "$pass" ]] || { echo "error: failed to register agent" >&2; exit 1; }
143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # Clean up registration on exit.
145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- trap 'echo "removing agent $nick..."; curl -sf -X DELETE \
146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- -H "Authorization: Bearer '"$token"'" \
147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "http://localhost:8080/v1/agents/$nick" >/dev/null || true' EXIT INT TERM
148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
149 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- echo "connecting as $nick..."
150 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- local backend="${SCUTTLEBOT_BACKEND:-anthro}"
151 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- bin/claude-agent \
152 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --irc 127.0.0.1:6667 \
153 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --nick "$nick" \
154 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --pass "$pass" \
155 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --channels "#general" \
156 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --api-url "http://localhost:8080" \
157 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --token "$token" \
158 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --backend "$backend"
159 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
160 84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
161 85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
case "$cmd" in
162 86 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
start)
163 87 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_build
164 88 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_start
165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- _sync_claude_agent
166 89 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
;;
167 90 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
stop)
168 91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_stop
169 92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
;;
170 93 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
restart)
171 94 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_stop || true
172 95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_build
173 96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_start
174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- _sync_claude_agent
175 97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
;;
176 98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
build)
177 99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_build
178 100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
;;
179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- agent)
180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- go build -o bin/claude-agent ./cmd/claude-agent
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- _run_agent "${@:2}"
182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ;;
183 101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
token)
184 102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_token
185 103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
;;
186 104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
log|logs)
187 105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
tail -f "$LOG_FILE"
@@ -199,9 +117,9 @@
199 117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
_stop || true
200 118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
rm -f "$BINARY" bin/scuttlectl "$LOG_FILE" "$PID_FILE"
201 119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
echo "clean"
202 120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
;;
203 121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*)
204 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- echo "usage: $0 {start|stop|restart|agent|build|token|log|test|e2e|clean}"
122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ echo "usage: $0 {start|stop|restart|build|token|log|test|e2e|clean}"
205 123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
exit 1
206 124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
;;
207 125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
esac
208 126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!