#!/usr/bin/env bash
# box-relay.sh — Lightweight Box Relay Client for Fleet Agent Containers.
#
# Enables fleet agents (646, pip, muse, opm) to access muse-cli level tools,
# spawn subagents, send sidechat DMs, and inspect threads over the secure
# exec-constrained HTTPS relay endpoint.
#
# Supports Bearer Token (EXEC_TOKEN or ~/.exec-token) AND SSH signature auth.
# Endpoint: https://exec.muse-dev.online/exec (or Tailscale https://100.123.153.75:8444/exec)
set -euo pipefail
EXEC_URL="${EXEC_URL:-https://exec.muse-dev.online/exec}"
AGENT="${BOX_AGENT:-${AGENT_NAME:-}}"
TOKEN="${EXEC_TOKEN:-}"
if [ -z "$TOKEN" ] && [ -f "$HOME/.exec-token" ]; then
TOKEN="$(cat "$HOME/.exec-token" | tr -d '[:space:]')"
fi
# Detect agent identity if not set
if [ -z "$AGENT" ]; then
if [ -f "$HOME/.agent-name" ]; then
AGENT="$(cat "$HOME/.agent-name" | tr -d '[:space:]')"
elif echo "$HOSTNAME" | grep -qi "646"; then
AGENT="646"
elif echo "$HOSTNAME" | grep -qi "pip"; then
AGENT="pip"
elif echo "$HOSTNAME" | grep -qi "muse"; then
AGENT="muse"
elif echo "$HOSTNAME" | grep -qi "opm"; then
AGENT="opm"
elif echo "$HOSTNAME" | grep -qi "dev"; then
AGENT="dev"
elif echo "$HOSTNAME" | grep -qi "def"; then
AGENT="def"
else
AGENT="646"
fi
fi
# Helper: POST to exec endpoint
call_exec() {
local op="$1"
local args_json="$2"
if [ -n "$TOKEN" ]; then
# Bearer token auth
local body
body=$(python3 -c "import json, sys; print(json.dumps({'op': sys.argv[1], 'args': json.loads(sys.argv[2])}))" "$op" "$args_json")
local res
res=$(curl -sk -sS -X POST "$EXEC_URL" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) Box-Relay/1.0" \
--data "$body")
echo "$res" | python3 -c "
import json, sys
try:
d = json.load(sys.stdin)
if 'stdout' in d:
sys.stdout.write(d['stdout'])
elif 'error' in d:
sys.stderr.write('Error: ' + str(d['error']) + '\n')
sys.exit(1)
else:
print(json.dumps(d, indent=2))
except Exception as e:
print(sys.stdin.read())
"
else
# Signature auth fallback
local key="${SSH_KEY:-$HOME/.ssh/id_frontdoor}"
if [ ! -f "$key" ] && [ -f "$HOME/.ssh/id_ed25519" ]; then
key="$HOME/.ssh/id_ed25519"
fi
local ident="operator-$AGENT"
if [ "$AGENT" = "super" ]; then
ident="super"
fi
local ts
ts=$(date +%s)
local nonce
nonce=$(python3 -c "import secrets; print(secrets.token_hex(16))")
local payload
payload=$(python3 -c "
import json, sys
op, args_json, ts, nonce = sys.argv[1:5]
args = json.loads(args_json)
print(json.dumps({'op': op, 'args': args, 'ts': int(ts), 'nonce': nonce}))
" "$op" "$args_json" "$ts" "$nonce")
local sig
sig=$(printf '%s' "$payload" | ssh-keygen -Y sign -f "$key" -n exec-constrained 2>/dev/null)
local body
body=$(python3 -c "
import json, sys
ident, payload, sig = sys.argv[1:4]
print(json.dumps({'identity': ident, 'payload': payload, 'signature': sig}))
" "$ident" "$payload" "$sig")
local res
res=$(curl -sk -sS -X POST "$EXEC_URL" \
-H "Content-Type: application/json" \
-H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) Box-Relay/1.0" \
--data "$body")
echo "$res" | python3 -c "
import json, sys
try:
d = json.load(sys.stdin)
if 'stdout' in d:
sys.stdout.write(d['stdout'])
elif 'error' in d:
sys.stderr.write('Error: ' + str(d['error']) + '\n')
sys.exit(1)
else:
print(json.dumps(d, indent=2))
except Exception as e:
print(sys.stdin.read())
"
fi
}
cmd="${1:-help}"
shift || true
case "$cmd" in
subagent)
sub="${1:-help}"
shift || true
case "$sub" in
spawn)
title="subagent"
wait=0
while [ $# -gt 0 ]; do
case "$1" in
--title) title="$2"; shift 2 ;;
--wait) wait="$2"; shift 2 ;;
--agent) AGENT="$2"; shift 2 ;;
*) break ;;
esac
done
prompt="${1:?usage: box subagent spawn [--title
] [--wait ] }"
args=$(python3 -c "import json, sys; print(json.dumps({'agent': sys.argv[1], 'title': sys.argv[2], 'prompt': sys.argv[3], 'wait': int(sys.argv[4])}))" "$AGENT" "$title" "$prompt" "$wait")
call_exec "subagent.spawn" "$args"
;;
*)
echo "Usage: box subagent spawn [--title ] [--wait ] "
;;
esac
;;
deploy)
sub="${1:-help}"
shift || true
case "$sub" in
subagent)
title="subagent"
wait=0
while [ $# -gt 0 ]; do
case "$1" in
--title) title="$2"; shift 2 ;;
--wait) wait="$2"; shift 2 ;;
--agent) AGENT="$2"; shift 2 ;;
*) break ;;
esac
done
prompt="${1:?usage: box deploy subagent [--title ] [--wait ] }"
args=$(python3 -c "import json, sys; print(json.dumps({'agent': sys.argv[1], 'title': sys.argv[2], 'prompt': sys.argv[3], 'wait': int(sys.argv[4])}))" "$AGENT" "$title" "$prompt" "$wait")
call_exec "subagent.spawn" "$args"
;;
pipeline)
name="${1:?usage: box deploy pipeline }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "pipeline.run" "$args"
;;
*)
echo "Usage: box deploy subagent|pipeline ..."
;;
esac
;;
dm)
sub="${1:-help}"
shift || true
case "$sub" in
send)
to=""
target=""
from_agent="$AGENT"
while [ $# -gt 0 ]; do
case "$1" in
--to) to="$2"; shift 2 ;;
--target) target="$2"; shift 2 ;;
--agent|--from) from_agent="$2"; shift 2 ;;
*) break ;;
esac
done
msg="${1:?usage: box dm send --to [--target ] }"
to="${to:-$AGENT}"
target="${target:-$AGENT-pip}"
args=$(python3 -c "import json, sys; print(json.dumps({'agent': sys.argv[1], 'to': sys.argv[2], 'target': sys.argv[3], 'message': sys.argv[4]}))" "$from_agent" "$to" "$target" "$msg")
call_exec "dm.send" "$args"
;;
read)
target="${1:-main}"
limit="${2:-10}"
args=$(python3 -c "import json, sys; print(json.dumps({'agent': sys.argv[1], 'target': sys.argv[2], 'limit': int(sys.argv[3])}))" "$AGENT" "$target" "$limit")
call_exec "dm.read" "$args"
;;
*)
echo "Usage: box dm send|read ..."
;;
esac
;;
thread)
sub="${1:-list}"
shift || true
case "$sub" in
list)
target_agent="${1:-$AGENT}"
args=$(python3 -c "import json, sys; print(json.dumps({'agent': sys.argv[1]}))" "$target_agent")
call_exec "thread.list" "$args"
;;
view)
target_agent="$AGENT"
while [ $# -gt 0 ]; do
case "$1" in
--agent) target_agent="$2"; shift 2 ;;
*) break ;;
esac
done
if [ $# -ge 2 ] && echo " 646 opm pip muse dev def " | grep -q " $1 "; then
target_agent="$1"
shift
fi
thread_id="${1:?usage: box thread view [] [limit]}"
limit="${2:-15}"
args=$(python3 -c "import json, sys; print(json.dumps({'agent': sys.argv[1], 'thread': sys.argv[2], 'limit': int(sys.argv[3])}))" "$target_agent" "$thread_id" "$limit")
call_exec "thread.view" "$args"
;;
*)
echo "Usage: box thread list|view ..."
;;
esac
;;
cron)
sub="${1:-runs}"
shift || true
case "$sub" in
runs|list)
call_exec "cron.runs" "{}"
;;
status)
name="${1:-heartbeat}"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "cron.status" "$args"
;;
view)
name="${1:?usage: box cron view }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "cron.view" "$args"
;;
run)
name="${1:?usage: box cron run }"
args=$(python3 -c "import json, sys; print(json.dumps({'job': sys.argv[1]}))" "$name")
call_exec "cron.run" "$args"
;;
timer-create)
name="${1:?usage: box cron timer-create }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "cron.timer_create" "$args"
;;
timer-start)
name="${1:?usage: box cron timer-start }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "cron.timer_start" "$args"
;;
*)
echo "Usage: box cron runs|status|view|run|timer-create|timer-start ..."
;;
esac
;;
timer)
sub="${1:-list}"
shift || true
case "$sub" in
create|set)
name="${1:?usage: box timer create }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "cron.timer_create" "$args"
;;
start|enable)
name="${1:?usage: box timer start }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "cron.timer_start" "$args"
;;
status|view|list)
name="${1:-heartbeat}"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "cron.status" "$args"
;;
*)
echo "Usage: box timer create|start|status "
;;
esac
;;
swarm)
sub="${1:-list}"
shift || true
case "$sub" in
spawn)
count="${1:?usage: box swarm spawn }"
shift
task="$*"
args=$(python3 -c "import json, sys; print(json.dumps({'count': int(sys.argv[1]), 'task': sys.argv[2]}))" "$count" "$task")
call_exec "swarm.spawn" "$args"
;;
status)
sid="${1:?usage: box swarm status }"
args=$(python3 -c "import json, sys; print(json.dumps({'swarm_id': sys.argv[1]}))" "$sid")
call_exec "swarm.status" "$args"
;;
list)
call_exec "swarm.list" "{}"
;;
*)
echo "Usage: box swarm spawn|status|list ..."
;;
esac
;;
vars)
sub="${1:-list}"
shift || true
case "$sub" in
list)
call_exec "vars.list" "{}"
;;
get)
name="${1:?usage: box vars get }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1]}))" "$name")
call_exec "vars.get" "$args"
;;
set)
name="${1:?usage: box vars set }"
val="${2:?usage: box vars set }"
args=$(python3 -c "import json, sys; print(json.dumps({'name': sys.argv[1], 'value': sys.argv[2]}))" "$name" "$val")
call_exec "vars.set" "$args"
;;
*)
echo "Usage: box vars list|get|set ..."
;;
esac
;;
files)
sub="${1:-read}"
shift || true
case "$sub" in
read)
path="${1:?usage: box files read [lines=100]}"
lines="${2:-100}"
args=$(python3 -c "import json, sys; print(json.dumps({'path': sys.argv[1], 'lines': int(sys.argv[2])}))" "$path" "$lines")
call_exec "files.read" "$args"
;;
write)
path="${1:?usage: box files write }"
content="${2:?usage: box files write }"
args=$(python3 -c "import json, sys; print(json.dumps({'path': sys.argv[1], 'content': sys.argv[2]}))" "$path" "$content")
call_exec "files.write" "$args"
;;
*)
echo "Usage: box files read|write ..."
;;
esac
;;
web)
sub="${1:-fetch}"
shift || true
case "$sub" in
fetch)
url="${1:?usage: box web fetch }"
args=$(python3 -c "import json, sys; print(json.dumps({'url': sys.argv[1]}))" "$url")
call_exec "web.fetch" "$args"
;;
*)
echo "Usage: box web fetch "
;;
esac
;;
service)
sub="${1:-status}"
shift || true
case "$sub" in
status)
unit="${1:?usage: box service status }"
args=$(python3 -c "import json, sys; print(json.dumps({'unit': sys.argv[1]}))" "$unit")
call_exec "service.status" "$args"
;;
restart)
unit="${1:?usage: box service restart }"
args=$(python3 -c "import json, sys; print(json.dumps({'unit': sys.argv[1]}))" "$unit")
call_exec "service.restart" "$args"
;;
*)
echo "Usage: box service status|restart "
;;
esac
;;
health)
call_exec "health.check" "{}"
;;
ping)
call_exec "exec.ping" "{}"
;;
ops)
curl -sk -sS "${EXEC_URL%/exec}/ops" | python3 -m json.tool
;;
help|--help|-h)
cat <] [--wait ]
box deploy subagent [--title ] [--wait ]
box deploy pipeline
box dm send --to [--target ]
box dm read [] []
box thread list []
box thread view []
box cron runs
box cron status []
box cron view
box cron run
box vars list
box vars get
box vars set
box files read [lines=100]
box files write
box web fetch
box service status
box service restart
box health
box ping
box ops
Configuration:
EXEC_URL Endpoint (default: https://exec.muse-dev.online/exec)
EXEC_TOKEN Bearer token (or store in ~/.exec-token)
BOX_AGENT Agent identity (646, pip, muse, opm)
EOF
;;
*)
echo "Unknown command: $cmd (run 'box help')"
exit 1
;;
esac