Skip to content

Commit a8bc265

Browse files
committed
ops: remove tmux-based bridge guidance and runtime paths
1 parent 59d3563 commit a8bc265

9 files changed

Lines changed: 116 additions & 153 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Baudbot is designed as shared engineering infrastructure, not a single-user desk
5252
| **CPU** | 2 vCPU | 4 vCPU |
5353
| **Disk** | 20 GB | 40 GB+ (repos, dependencies, Docker images) |
5454

55-
System package dependencies (installed by `baudbot install`): `git`, `curl`, `tmux`, `iptables`, `docker`, `gh`, `jq`, `sudo`.
55+
System package dependencies (installed by `baudbot install`): `git`, `curl`, `iptables`, `docker`, `gh`, `jq`, `sudo`.
5656

5757
## Quick Start
5858

bin/baudbot

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ usage() {
131131
echo " restart Restart the agent"
132132
echo " status Show agent status + deployed version + broker connection"
133133
echo " logs Tail agent logs"
134-
echo " attach Attach to control-agent by default; supports --pi/--tmux"
135-
echo " sessions List agent tmux and pi sessions (name → id)"
134+
echo " attach Attach to a running pi session (defaults to control-agent)"
135+
echo " sessions List live pi sessions (name → id)"
136136
echo ""
137137
echo -e "${BOLD}Setup:${RESET}"
138138
echo " install Bootstrap install from GitHub (download script, then escalate)"
@@ -351,16 +351,6 @@ case "${1:-}" in
351351
shift
352352
require_root "restart"
353353
if has_systemd; then
354-
# Ensure any pre-existing detached bridge tmux session is torn down so
355-
# restart always boots a fresh bridge from currently deployed runtime files.
356-
AGENT_USER="${BAUDBOT_AGENT_USER:-baudbot_agent}"
357-
if command -v tmux >/dev/null 2>&1; then
358-
if command -v sudo >/dev/null 2>&1; then
359-
sudo -u "$AGENT_USER" tmux kill-session -t slack-bridge 2>/dev/null || true
360-
elif command -v runuser >/dev/null 2>&1; then
361-
runuser -u "$AGENT_USER" -- tmux kill-session -t slack-bridge 2>/dev/null || true
362-
fi
363-
fi
364354
exec systemctl restart baudbot "$@"
365355
else
366356
echo "systemd not available."

bin/baudbot.test.sh

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ EOF
130130
)
131131
}
132132

133-
test_restart_restarts_systemd_and_kills_bridge_tmux() {
133+
test_restart_restarts_systemd() {
134134
(
135135
set -euo pipefail
136136
local tmp fakebin log_file
@@ -168,12 +168,6 @@ if [ "${1:-}" = "-u" ]; then
168168
fi
169169
echo "sudo $*" >> "${BAUDBOT_TEST_LOG}"
170170
exec "$@"
171-
EOF
172-
173-
cat > "$fakebin/tmux" <<'EOF'
174-
#!/bin/bash
175-
echo "tmux $*" >> "${BAUDBOT_TEST_LOG}"
176-
exit 0
177171
EOF
178172

179173
cat > "$fakebin/systemctl" <<'EOF'
@@ -182,11 +176,10 @@ echo "systemctl $*" >> "${BAUDBOT_TEST_LOG}"
182176
exit 0
183177
EOF
184178

185-
chmod +x "$fakebin/id" "$fakebin/sudo" "$fakebin/tmux" "$fakebin/systemctl"
179+
chmod +x "$fakebin/id" "$fakebin/sudo" "$fakebin/systemctl"
186180

187181
PATH="$fakebin:$PATH" BAUDBOT_TEST_LOG="$log_file" BAUDBOT_ROOT="$tmp" bash "$CLI" restart
188182

189-
grep -q '^tmux kill-session -t slack-bridge$' "$log_file"
190183
grep -q '^systemctl restart baudbot$' "$log_file"
191184
)
192185
}
@@ -198,7 +191,7 @@ run_test "version reads package.json" test_version_uses_package_json
198191
run_test "status dispatches via runtime module" test_status_dispatches_via_runtime_module
199192
run_test "attach requires root" test_attach_requires_root
200193
run_test "broker register requires root" test_broker_register_requires_root
201-
run_test "restart kills bridge tmux then restarts systemd" test_restart_restarts_systemd_and_kills_bridge_tmux
194+
run_test "restart restarts systemd" test_restart_restarts_systemd
202195

203196
echo ""
204197
echo "=== $PASSED/$TOTAL passed, $FAILED failed ==="

bin/lib/baudbot-runtime.sh

Lines changed: 15 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,9 @@ cmd_logs() {
305305
exec journalctl -u baudbot -f "$@"
306306
fi
307307

308-
echo "No systemd unit. Check tmux sessions:"
309-
echo " sudo -u baudbot_agent tmux ls"
308+
echo "No systemd unit. Check process + logs:"
309+
echo " pgrep -u baudbot_agent -af 'pi --session-control'"
310+
echo " tail -n 200 /home/baudbot_agent/.pi/agent/logs/runtime.log"
310311
}
311312

312313
cmd_sessions() {
@@ -316,14 +317,6 @@ cmd_sessions() {
316317
local found alias alias_name alias_uuid sock sess_id name status
317318
declare -A ALIASES
318319

319-
echo -e "${BOLD}tmux sessions:${RESET}"
320-
if sudo -u "$AGENT_USER" tmux ls 2>/dev/null; then
321-
:
322-
else
323-
echo " (none)"
324-
fi
325-
326-
echo ""
327320
echo -e "${BOLD}pi sessions:${RESET}"
328321
PI_CONTROL_DIR="$(pi_control_dir "$AGENT_USER")"
329322
if [ ! -d "$PI_CONTROL_DIR" ]; then
@@ -377,28 +370,26 @@ cmd_attach() {
377370

378371
local AGENT_USER="baudbot_agent"
379372
local AGENT_HOME="/home/$AGENT_USER"
380-
local ATTACH_MODE="auto"
381373
local TARGET=""
382-
local tmux_target pi_target
374+
local pi_target
383375

384376
while [ "$#" -gt 0 ]; do
385377
case "$1" in
386378
--pi)
387-
ATTACH_MODE="pi"
379+
# Backward-compatible no-op (pi is the only supported mode now)
388380
shift
389381
;;
390382
--tmux)
391-
ATTACH_MODE="tmux"
392-
shift
383+
echo "❌ --tmux is no longer supported. Use: sudo baudbot attach [session-name|session-id]"
384+
exit 1
393385
;;
394386
-h|--help)
395-
echo "Usage: sudo baudbot attach [--pi|--tmux] [session-name|session-id]"
387+
echo "Usage: sudo baudbot attach [session-name|session-id]"
396388
echo ""
397389
echo "Examples:"
398390
echo " sudo baudbot attach # defaults to control-agent"
399-
echo " sudo baudbot attach --pi control-agent"
400-
echo " sudo baudbot attach --pi <uuid>"
401-
echo " sudo baudbot attach --tmux slack-bridge"
391+
echo " sudo baudbot attach control-agent"
392+
echo " sudo baudbot attach <uuid>"
402393
exit 0
403394
;;
404395
*)
@@ -416,82 +407,22 @@ cmd_attach() {
416407
TARGET="control-agent"
417408
fi
418409

419-
attach_tmux_session() {
420-
local tmux_target="$1"
421-
echo -e "${BOLD}${CYAN}Attaching to tmux session:${RESET} $tmux_target"
422-
echo -e "${GREEN}Safe detach:${RESET} Ctrl+b, d ${DIM}(keeps agent running)${RESET}"
423-
echo ""
424-
pause_before_attach
425-
exec sudo -u "$AGENT_USER" tmux attach-session -t "$tmux_target"
426-
}
427-
428410
attach_pi_session() {
429-
local pi_target="$1"
430-
echo -e "${BOLD}${CYAN}Attaching to pi session:${RESET} $pi_target"
411+
local target_session="$1"
412+
echo -e "${BOLD}${CYAN}Attaching to pi session:${RESET} $target_session"
431413
echo -e "${BOLD}${YELLOW}Safe detach (does NOT stop the agent):${RESET}"
432414
echo -e " ${YELLOW}1)${RESET} Press Ctrl+C once to clear input/cancel local prompt"
433415
echo -e " ${YELLOW}2)${RESET} Press Ctrl+C again to exit this client"
434416
echo -e " ${GREEN}Agent keeps running under systemd in the background.${RESET}"
435417
echo ""
436418
pause_before_attach
437-
exec sudo -u "$AGENT_USER" bash -lc "export PATH='$AGENT_HOME/.varlock/bin:$AGENT_HOME/opt/node-v22.14.0-linux-x64/bin':\$PATH; cd ~; varlock run --path ~/.config/ -- pi --session '$pi_target'"
438-
}
439-
440-
choose_tmux_target() {
441-
local requested="${1:-}"
442-
local first
443-
444-
if [ -n "$requested" ]; then
445-
if sudo -u "$AGENT_USER" tmux has-session -t "$requested" 2>/dev/null; then
446-
echo "$requested"
447-
return 0
448-
fi
449-
return 1
450-
fi
451-
452-
first=$(sudo -u "$AGENT_USER" tmux ls -F '#{session_name}' 2>/dev/null | head -1)
453-
[ -n "$first" ] || return 1
454-
echo "$first"
455-
return 0
456-
}
457-
458-
choose_pi_target() {
459-
local requested="${1:-}"
460-
local resolved
461-
462-
if ! resolved=$(resolve_pi_session_id "$AGENT_USER" "$requested"); then
463-
return 1
464-
fi
465-
466-
[ -n "$resolved" ] || return 1
467-
echo "$resolved"
468-
return 0
419+
exec sudo -u "$AGENT_USER" bash -lc "export PATH='$AGENT_HOME/.varlock/bin:$AGENT_HOME/opt/node-v22.14.0-linux-x64/bin':\$PATH; cd ~; varlock run --path ~/.config/ -- pi --session '$target_session'"
469420
}
470421

471-
if [ "$ATTACH_MODE" = "tmux" ]; then
472-
if tmux_target=$(choose_tmux_target "$TARGET"); then
473-
attach_tmux_session "$tmux_target"
474-
fi
475-
echo "❌ tmux session not found. See: sudo baudbot sessions"
476-
exit 1
477-
fi
478-
479-
if [ "$ATTACH_MODE" = "pi" ]; then
480-
if pi_target=$(choose_pi_target "$TARGET"); then
481-
attach_pi_session "$pi_target"
482-
fi
483-
echo "❌ pi session not found. See: sudo baudbot sessions"
484-
exit 1
485-
fi
486-
487-
if pi_target=$(choose_pi_target "$TARGET"); then
422+
if pi_target=$(resolve_pi_session_id "$AGENT_USER" "$TARGET"); then
488423
attach_pi_session "$pi_target"
489424
fi
490425

491-
if tmux_target=$(choose_tmux_target "$TARGET"); then
492-
attach_tmux_session "$tmux_target"
493-
fi
494-
495-
echo "❌ No matching tmux/pi session found. See: sudo baudbot sessions"
426+
echo "❌ pi session not found. See: sudo baudbot sessions"
496427
exit 1
497428
}

install.sh

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ install_prereqs_ubuntu() {
163163

164164
for attempt in $(seq 1 5); do
165165
if DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=120 update -qq \
166-
&& DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=120 install -y -qq git curl tmux iptables docker.io gh jq sudo 2>&1 | tail -3; then
166+
&& DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=120 install -y -qq git curl iptables docker.io gh jq sudo 2>&1 | tail -3; then
167167
return 0
168168
fi
169169

@@ -179,10 +179,10 @@ install_prereqs_ubuntu() {
179179
}
180180

181181
install_prereqs_arch() {
182-
pacman -Syu --noconfirm --needed git curl tmux iptables docker github-cli jq sudo 2>&1 | tail -5
182+
pacman -Syu --noconfirm --needed git curl iptables docker github-cli jq sudo 2>&1 | tail -5
183183
}
184184

185-
info "Installing: git, curl, tmux, iptables, docker, gh, jq, sudo"
185+
info "Installing: git, curl, iptables, docker, gh, jq, sudo"
186186
"install_prereqs_$DISTRO"
187187
info "Prerequisites installed"
188188

@@ -318,12 +318,15 @@ else
318318
warn "Agent didn't start — check: baudbot logs"
319319
fi
320320
else
321-
sudo -u baudbot_agent tmux new-session -d -s baudbot "$BAUDBOT_HOME/runtime/start.sh" 2>/dev/null || true
321+
RUNTIME_LOG_DIR="$BAUDBOT_HOME/.pi/agent/logs"
322+
RUNTIME_LOG_FILE="$RUNTIME_LOG_DIR/runtime.log"
323+
sudo -u baudbot_agent mkdir -p "$RUNTIME_LOG_DIR"
324+
sudo -u baudbot_agent bash -lc "nohup '$BAUDBOT_HOME/runtime/start.sh' >> '$RUNTIME_LOG_FILE' 2>&1 &"
322325
sleep 2
323-
if sudo -u baudbot_agent tmux has-session -t baudbot 2>/dev/null; then
326+
if pgrep -u baudbot_agent -f "pi --session-control" >/dev/null 2>&1; then
324327
info "Agent is running ✓"
325328
else
326-
warn "Agent didn't start — try: baudbot start --direct"
329+
warn "Agent didn't start — check: $RUNTIME_LOG_FILE"
327330
fi
328331
fi
329332
else

pi/skills/control-agent/SKILL.md

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -198,19 +198,22 @@ git fetch origin
198198
git worktree add ~/workspace/worktrees/$BRANCH -b $BRANCH origin/main
199199

200200
# 2. Launch the agent IN the worktree
201-
tmux new-session -d -s $SESSION_NAME \
202-
"cd ~/workspace/worktrees/$BRANCH && \
203-
export PATH=\$HOME/.varlock/bin:\$HOME/opt/node-v22.14.0-linux-x64/bin:\$PATH && \
204-
export PI_SESSION_NAME=$SESSION_NAME && \
205-
exec varlock run --path ~/.config/ -- pi --session-control --skill ~/.pi/agent/skills/dev-agent --model <MODEL_FROM_TABLE_ABOVE>"
201+
mkdir -p ~/.pi/agent/logs
202+
nohup bash -lc "cd ~/workspace/worktrees/$BRANCH && \
203+
export PATH=\$HOME/.varlock/bin:\$HOME/opt/node-v22.14.0-linux-x64/bin:\$PATH && \
204+
export PI_SESSION_NAME=$SESSION_NAME && \
205+
exec varlock run --path ~/.config/ -- pi --session-control --skill ~/.pi/agent/skills/dev-agent --model <MODEL_FROM_TABLE_ABOVE>" \
206+
> ~/.pi/agent/logs/$SESSION_NAME.log 2>&1 &
207+
DEV_PID=$!
208+
echo $DEV_PID > ~/.pi/agent/$SESSION_NAME.pid
206209
```
207210

208211
**Important notes:**
209212
- `cd` into the worktree BEFORE launching pi — this ensures pi discovers project context from the repo's CWD
210-
- Use `exec` so the tmux session exits when pi exits
211213
- Use `varlock run --path ~/.config/` to validate and inject env vars
212214
- Set `PI_SESSION_NAME` so the auto-name extension registers it
213215
- Include `--session-control` for `send_to_session` / `list_sessions`
216+
- Read logs with `tail -f ~/.pi/agent/logs/$SESSION_NAME.log`
214217
- Wait **~10 seconds** after spawning before sending messages (agent needs time to initialize)
215218
- Do NOT use `--name` (not a real pi CLI flag)
216219

@@ -225,8 +228,13 @@ SESSION_NAME=dev-agent-myapp-a8b7b331
225228
REPO=myapp
226229
BRANCH=fix/some-descriptive-name
227230

228-
# 1. Kill the tmux session (agent should have already exited, but ensure it)
229-
tmux kill-session -t $SESSION_NAME 2>/dev/null || true
231+
# 1. Kill the process if still running
232+
PID_FILE=~/.pi/agent/$SESSION_NAME.pid
233+
if [ -f "$PID_FILE" ]; then
234+
PID=$(cat "$PID_FILE" 2>/dev/null || true)
235+
[ -n "$PID" ] && kill "$PID" 2>/dev/null || true
236+
rm -f "$PID_FILE"
237+
fi
230238

231239
# 2. Remove the worktree
232240
cd ~/workspace/$REPO
@@ -309,10 +317,10 @@ This removes stale `.sock` files, cleans dead aliases, and restarts the Slack br
309317
- [ ] Find or create sentry-agent:
310318
1. Use `list_sessions` to look for a session named `sentry-agent`
311319
2. If found, use that session
312-
3. If not found, launch with tmux (see Sentry Agent section)
320+
3. If not found, launch as a normal background process (see Sentry Agent section)
313321
4. Wait ~8 seconds, then send role assignment
314322
- [ ] Send role assignment to the `sentry-agent` session
315-
- [ ] Clean up any stale dev-agent worktrees/tmux sessions from previous runs
323+
- [ ] Clean up any stale dev-agent worktrees/background processes from previous runs
316324

317325
**Note**: Dev agents are NOT started at startup. They are spawned on-demand when tasks arrive.
318326

@@ -330,7 +338,9 @@ The sentry-agent triages Sentry alerts and investigates critical issues via the
330338
| `OPENCODE_ZEN_API_KEY` | `opencode-zen/claude-haiku-4-5` |
331339

332340
```bash
333-
tmux new-session -d -s sentry-agent "export PATH=\$HOME/.varlock/bin:\$HOME/opt/node-v22.14.0-linux-x64/bin:\$PATH && export PI_SESSION_NAME=sentry-agent && varlock run --path ~/.config/ -- pi --session-control --skill ~/.pi/agent/skills/sentry-agent --model <MODEL_FROM_TABLE_ABOVE>"
341+
mkdir -p ~/.pi/agent/logs
342+
nohup bash -lc "export PATH=\$HOME/.varlock/bin:\$HOME/opt/node-v22.14.0-linux-x64/bin:\$PATH && export PI_SESSION_NAME=sentry-agent && exec varlock run --path ~/.config/ -- pi --session-control --skill ~/.pi/agent/skills/sentry-agent --model <MODEL_FROM_TABLE_ABOVE>" > ~/.pi/agent/logs/sentry-agent.log 2>&1 &
343+
echo $! > ~/.pi/agent/sentry-agent.pid
334344
```
335345

336346
**Model note**: `github-copilot/*` models reject Personal Access Tokens and will fail in non-interactive sessions.
@@ -339,17 +349,14 @@ The sentry-agent operates in **on-demand mode** — it does NOT poll. Sentry ale
339349

340350
### Starting the Slack Bridge
341351

342-
The `startup-cleanup.sh` script handles bridge (re)start automatically — it detects broker vs Socket Mode, reads the control-agent UUID, and launches the bridge in a `slack-bridge` tmux session.
352+
The `startup-cleanup.sh` script handles bridge (re)start automatically — it detects broker vs Socket Mode, reads the control-agent UUID, and starts the bridge as a normal background process.
343353

344-
If you need to restart the bridge manually:
354+
If you need to restart the bridge manually, run `startup-cleanup.sh` again and then inspect logs:
345355
```bash
346-
MY_UUID=$(readlink ~/.pi/session-control/control-agent.alias | sed 's/.sock$//')
347-
tmux kill-session -t slack-bridge 2>/dev/null || true
348-
tmux new-session -d -s slack-bridge \
349-
"unset PKG_EXECPATH; export PATH=\$HOME/.varlock/bin:\$HOME/opt/node-v22.14.0-linux-x64/bin:\$PATH && export PI_SESSION_ID=$MY_UUID && cd ~/runtime/slack-bridge && exec varlock run --path ~/.config/ -- node broker-bridge.mjs"
356+
tail -n 200 ~/.pi/agent/logs/slack-bridge.log
350357
```
351358

352-
Verify: `curl -s -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:7890/send -H 'Content-Type: application/json' -d '{}'` → should return `400`.
359+
Verify API readiness: `curl -s -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:7890/send -H 'Content-Type: application/json' -d '{}'` → should return `400`.
353360

354361
The bridge forwards:
355362
- **Human @mentions and DMs** from allowed users → delivered to you with security boundaries for handling
@@ -362,9 +369,9 @@ Health checks run automatically every ~10 minutes via the `heartbeat.ts` extensi
362369
If you need to check manually, use `heartbeat trigger` to run all checks immediately.
363370

364371
When the heartbeat reports a failure, take the appropriate action:
365-
1. **Missing sentry-agent**: Respawn with tmux and re-send role assignment.
366-
2. **Orphaned dev-agents**: Kill tmux session and remove worktree.
367-
3. **Bridge down**: Restart the `slack-bridge` tmux session.
372+
1. **Missing sentry-agent**: Respawn as a background process and re-send role assignment.
373+
2. **Orphaned dev-agents**: Kill stale process + remove worktree.
374+
3. **Bridge down**: Restart via `startup-cleanup.sh` and read `~/.pi/agent/logs/slack-bridge.log`.
368375
4. **Stale worktrees**: `git worktree remove --force` + `rmdir` empty parents.
369376
5. **Stuck todos**: Escalate to user via Slack.
370377

pi/skills/control-agent/memory/operational.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ Add entries under dated headings. Keep entries concise — one line per learning
88
<!-- Example:
99
## 2026-02-17
1010
- Stale `.sock` files cause bridge "connect ENOENT" errors. Always run `startup-cleanup.sh` with live UUIDs on boot.
11-
- `varlock run` must be used (not `source .env`) when launching agents in tmux — ensures schema validation.
11+
- `varlock run` must be used (not `source .env`) when launching agents in background processes — ensures schema validation.
1212
-->

0 commit comments

Comments
 (0)