Bullybuddy

BullyBuddy — Claude Code session manager CLI wrapper. Spawn, list, send input, kill, and monitor multiple Claude Code sessions via /bullybuddy slash command. Reads auth token from ~/.bullybuddy/connection.json automatically.

Audits

Pending

Install

openclaw skills install bullybuddy

BullyBuddy

Spawns and manages multiple Claude Code CLI sessions. Dual backend: tmux (default, sessions survive server restart) or node-pty (fallback). REST API, WebSocket streaming, web dashboard.

Setup

  1. Install the package globally:
npm install -g openclaw-bullybuddy
  1. Start the server:
bullybuddy server

Connection info is auto-saved to ~/.bullybuddy/connection.json on startup. The /bullybuddy command reads it automatically — no env vars needed.

For remote access, start with bullybuddy server --tunnel. The tunnel URL is available via /bullybuddy url.

/bullybuddy Slash Command

/bullybuddy status          - Server status & session summary
/bullybuddy list            - List all sessions
/bullybuddy spawn [cwd] [task] [group] - Create new session
/bullybuddy send <id> <text> - Send input to session
/bullybuddy output <id> [lines] - Show session output/transcript
/bullybuddy kill <id>       - Terminate session
/bullybuddy url             - Show dashboard URL (local + tunnel)
/bullybuddy audit [limit]   - View audit log
/bullybuddy transcript <id> [limit] - View conversation transcript
/bullybuddy help            - Show help

Security Notice

  • The auth token grants full control over all spawned Claude Code sessions, including sending arbitrary input. Treat it as a secret.
  • The /bullybuddy url command outputs the dashboard URL with the token embedded. Do not share or log this URL publicly.
  • When using --tunnel, the dashboard and API are exposed to the internet via a Cloudflare temporary URL. Anyone with the token can access all sessions remotely.
  • Spawned sessions run Claude Code with your local permissions. If --dangerously-skip-permissions is enabled, Claude can execute any command without confirmation.

Authentication

A random token is generated on each server start and saved to ~/.bullybuddy/connection.json (mode 0600). CLI and /bullybuddy auto-discover it. For the dashboard, the token is included in the URL printed on startup. The connection file is deleted on graceful shutdown.

API Overview

All endpoints require the token via Authorization: Bearer <token> header or ?token= query parameter. All responses follow { ok: boolean, data?: T, error?: string }.

MethodEndpointDescription
GET/healthServer status
GET/api/sessionsList sessions (filter by group)
POST/api/sessionsSpawn session
GET/api/sessions/:idSession detail with metrics
DELETE/api/sessions/:idKill session
POST/api/sessions/:id/inputSend input to PTY
POST/api/sessions/:id/resizeResize PTY
POST/api/sessions/:id/taskSet task metadata
POST/api/sessions/:id/muteMute notifications
POST/api/sessions/:id/unmuteUnmute notifications
GET/api/groupsGroups with session counts
GET/api/summaryAggregate state counts and groups
GET/api/browseBrowse directories (disabled by default)
GET/api/auditAudit log
GET/api/sessions/:id/transcriptConversation transcript

Spawn Request Body

{
  "name": "worker-1",
  "group": "myproject",
  "cwd": "/path/to/repo",
  "task": "Implement feature X",
  "args": ["--verbose"],
  "cols": 120,
  "rows": 40,
  "skipPermissions": false
}

All fields optional. When task is provided, it is automatically sent as input when Claude reaches the idle prompt.

Note: When sending input, terminate with \r (carriage return), not \n.

WebSocket Protocol

Connect to ws://<host>:<port>/ws?token=<token>.

Client Messages

typefieldsdescription
subscribesessionId, cols?, rows?Receive output from session
unsubscribesessionIdStop receiving output
inputsessionId, dataSend keystrokes to PTY
resizesessionId, cols, rowsResize PTY

Server Messages

typefieldsdescription
sessionssessions[]Full session list (on connect)
outputsessionId, dataTerminal output chunk
scrollbacksessionId, dataBuffered scrollback on subscribe
session:createdsessionNew session spawned
session:exitedsessionId, exitCodeSession terminated
session:stateChangedsessionId, detailedStateState transition
errormessageError (e.g. invalid message)

State Detection

BullyBuddy analyzes raw PTY output to detect Claude Code's state in real-time.

detailedStateMeaning
startingSession just spawned, Claude loading
workingClaude is thinking/editing (spinner visible)
permission_neededClaude waiting for user approval
idleClaude at prompt, ready for input
compactingCompacting conversation history
errorError detected in output

State transitions are broadcast via WebSocket and reflected in GET /api/summary.

OpenClaw Integration

Poll GET /api/summary on an interval to check fleet status. The sessionsNeedingAttention field contains IDs of sessions in permission_needed or error state.

Remote Access

Start the server with --tunnel to create a Cloudflare temporary URL automatically:

bullybuddy server --tunnel

The tunnel URL is printed on startup and saved to ~/.bullybuddy/connection.json. Use bullybuddy url or /bullybuddy url to retrieve it anytime.

CLI Commands

bullybuddy server                          # Start server
bullybuddy server --tunnel                 # Start with Cloudflare tunnel
bullybuddy url                             # Show dashboard URL (local + tunnel)
bullybuddy spawn --name worker --group proj  # Spawn session
bullybuddy list --json                     # List sessions
bullybuddy send <id> "Fix the bug"         # Send input
bullybuddy attach <id>                     # Interactive terminal
bullybuddy kill <id>                       # Kill session
bullybuddy groups                          # List groups
bullybuddy open                            # Open dashboard

Script

When invoked, run:

{baseDir}/scripts/bullybuddy.sh $ARGUMENTS