diff --git a/live/operator-session/clawdie-join-hive.sh b/live/operator-session/clawdie-join-hive.sh index d138a022..1d0984d4 100755 --- a/live/operator-session/clawdie-join-hive.sh +++ b/live/operator-session/clawdie-join-hive.sh @@ -2,11 +2,33 @@ # One-click "Join Hive" โ€” registers this machine as a Colibri agent. # Runs in a visible terminal so the operator sees the result. # Idempotent: safe to re-run on an already-registered agent. -set -e SOCKET="${COLIBRI_SOCKET:-/var/run/colibri/colibri.sock}" PROVIDER_ENV="/usr/local/etc/colibri/provider.env" +finish() { + _code="${1:-0}" + echo "" + echo "Press Enter to close." + read -r _ + exit "${_code}" +} + +have() { + command -v "$1" >/dev/null 2>&1 +} + +provider_env_has_bw_creds() { + _check='test -f "$1" && grep -Eq "^BW_CLIENTID=.+" "$1" && grep -Eq "^BW_CLIENTSECRET=.+" "$1" && grep -Eq "^BW_PASSWORD=.+" "$1"' + + if have mdo; then + mdo -u root sh -c "${_check}" sh "${PROVIDER_ENV}" >/dev/null 2>&1 + return $? + fi + + sh -c "${_check}" sh "${PROVIDER_ENV}" >/dev/null 2>&1 +} + echo "========================================" echo " Clawdie โ€” Join Hive" echo "========================================" @@ -15,56 +37,108 @@ echo "" # 1. Check daemon if [ ! -S "$SOCKET" ]; then echo "[1/4] Starting colibri daemon..." - mdo -u root service colibri_daemon start - sleep 2 + if have mdo; then + if ! mdo -u root service colibri_daemon start; then + echo " WARNING: could not start colibri_daemon via mdo." + fi + elif [ "$(id -u)" -eq 0 ]; then + if ! service colibri_daemon start; then + echo " WARNING: could not start colibri_daemon." + fi + else + echo " WARNING: mdo is unavailable and this user is not root." + fi + + _tries=0 + while [ "$_tries" -lt 5 ] && [ ! -S "$SOCKET" ]; do + sleep 1 + _tries=$(( _tries + 1 )) + done else echo "[1/4] Daemon already running." fi -# 2. Vault creds +if [ ! -S "$SOCKET" ]; then + echo " ERROR: Colibri socket is still missing: ${SOCKET}" + echo " Check: mdo -u root service colibri_daemon status" + finish 1 +fi + +# 2. Vault creds. provider.env is intentionally 0600, so check via mdo when possible. echo "[2/4] Checking vault credentials..." -if [ -f "$PROVIDER_ENV" ] && grep -q 'BW_CLIENTID=.' "$PROVIDER_ENV" 2>/dev/null; then - echo " provider.env present with credentials." +if provider_env_has_bw_creds; then + echo " provider.env contains Vaultwarden bootstrap credential fields." else - echo " WARNING: provider.env missing or empty." - echo " Vault provisioning will be skipped." - echo " Edit ${PROVIDER_ENV} and re-run." + echo " WARNING: provider.env is missing, unreadable, or lacks BW_CLIENTID/BW_CLIENTSECRET/BW_PASSWORD." + echo " Vault provisioning will be skipped until the operator adds them." + echo " Edit ${PROVIDER_ENV} and keep it mode 0600, then re-run." fi # 3. Detect capabilities -HOST=$(hostname) -OS=$(uname -s | tr '[:upper:]' '[:lower:]') +HOST=$(hostname 2>/dev/null || echo "clawdie-live") +OS=$(uname -s 2>/dev/null | tr '[:upper:]' '[:lower:]') +[ -n "$OS" ] || OS="unknown" CAPS="$OS,shell" # Add optional capabilities -which colibri >/dev/null 2>&1 && CAPS="$CAPS,colibri" -which hermes >/dev/null 2>&1 && CAPS="$CAPS,hermes" -which pi >/dev/null 2>&1 && CAPS="$CAPS,pi" -tailscale status >/dev/null 2>&1 && CAPS="$CAPS,tailscale" +have colibri && CAPS="$CAPS,colibri" +have hermes && CAPS="$CAPS,hermes" +have pi && CAPS="$CAPS,pi" +if have tailscale && tailscale status >/dev/null 2>&1; then + CAPS="$CAPS,tailscale" +fi [ "$OS" = "freebsd" ] && CAPS="$CAPS,rc.d,jail,zfs" +if have python3; then + CAPS_JSON=$(printf '%s' "$CAPS" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read().strip().split(",")))' 2>/dev/null) +else + CAPS_JSON='["shell"]' +fi +[ -n "$CAPS_JSON" ] || CAPS_JSON='["shell"]' + AGENT_NAME="${HOST}" echo "[3/4] Registering agent: ${AGENT_NAME}" echo " capabilities: ${CAPS}" +if ! have nc; then + echo " ERROR: nc is not installed; cannot talk to ${SOCKET}." + finish 1 +fi + RESP=$(printf '{"cmd":"register-agent","name":"%s","capabilities":%s}\n' \ - "$AGENT_NAME" "$(echo "$CAPS" | python3 -c "import sys; print(__import__('json').dumps(sys.stdin.read().strip().split(',')))")" \ + "$AGENT_NAME" "$CAPS_JSON" \ | nc -U "$SOCKET" -w 3 2>/dev/null) if echo "$RESP" | grep -q '"ok":true'; then echo " registered." -elif echo "$RESP" | grep -q 'already exists'; then +elif echo "$RESP" | grep -Eiq 'already exists|unique constraint|constraint failed|agents\.name'; then echo " already registered (idempotent)." else - echo " registration note: ${RESP}" + echo " registration did not complete cleanly." + if [ -n "$RESP" ]; then + echo " response: ${RESP}" + else + echo " no response from ${SOCKET}" + fi + finish 1 fi -# 4. Start poll loop +# 4. Apply identity wallpaper as visual confirmation echo "[4/4] Agent ${AGENT_NAME} is live on the Colibri board." echo "" + +if have clawdie-wallpaper-gen; then + echo " Setting identity wallpaper..." + if have xfconf-query; then + WP="/tmp/clawdie-wallpaper.png" + clawdie-wallpaper-gen "$WP" 2>/dev/null && \ + xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitor0/workspace0/last-image -s "$WP" 2>/dev/null + fi +fi + echo " Check: colibri status" echo " Tasks: colibri list-tasks --status started" echo " Board: colibri list-agents" echo "" -echo "Hive joined. Press Enter to close." -read -r _ +echo "Hive joined." +finish 0 diff --git a/live/operator-session/colibri-panel-indicator.sh b/live/operator-session/colibri-panel-indicator.sh index 09213f6c..11465ef5 100755 --- a/live/operator-session/colibri-panel-indicator.sh +++ b/live/operator-session/colibri-panel-indicator.sh @@ -1,32 +1,39 @@ #!/bin/sh # xfce4-genmon panel indicator โ€” polls colibri daemon health. -# Install: add a Generic Monitor panel item pointing to this script. -# Refresh interval: 30s. -# -# Output: green/red dot + agent count + task count. +# Wired into a Generic Monitor panel item with 30s refresh. +# Output: genmon XML with green/red dot + agent count + task count. # ๐ŸŸข 2 agents ยท 3 tasks # ๐Ÿ”ด daemon down SOCKET="${COLIBRI_SOCKET:-/var/run/colibri/colibri.sock}" -TOOLTIP="" -if [ -S "$SOCKET" ]; then - STATUS=$(printf '{"cmd":"status"}\n' | nc -U "$SOCKET" -w 2 2>/dev/null) - if [ -n "$STATUS" ]; then - AGENTS=$(echo "$STATUS" | python3 -c "import sys,json; d=json.load(sys.stdin)['data']; print(d['agents'])" 2>/dev/null) - TASKS=$(echo "$STATUS" | python3 -c "import sys,json; d=json.load(sys.stdin)['data']; t=d['tasks']; print(t['started'])" 2>/dev/null) - HOST=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['host'])" 2>/dev/null) +have() { + command -v "$1" >/dev/null 2>&1 +} - echo "๐ŸŸข ${AGENTS} agents ยท ${TASKS} tasks" - TOOLTIP="Colibri: ${HOST} | socket: ${SOCKET} | agents: ${AGENTS} | started tasks: ${TASKS}" - else - echo "๐Ÿ”ด no response" - TOOLTIP="Colibri socket exists but not responding" - fi -else - echo "๐Ÿ”ด down" - TOOLTIP="Colibri daemon not running (no socket at ${SOCKET})" +if ! have nc || ! have python3; then + echo "โš  missing deps" + echo "nc and python3 required for colibri panel indicator" + exit 0 fi -echo "${TOOLTIP}" +if [ ! -S "$SOCKET" ]; then + echo "๐Ÿ”ด down" + echo "Colibri daemon not running (no socket at ${SOCKET})" + exit 0 +fi + +STATUS=$(printf '{"cmd":"status"}\n' | nc -U "$SOCKET" -w 2 2>/dev/null) +if [ -z "$STATUS" ]; then + echo "๐Ÿ”ด no response" + echo "Colibri socket exists but not responding" + exit 0 +fi + +AGENTS=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['agents'])" 2>/dev/null) +TASKS=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['tasks']['started'])" 2>/dev/null) +HOST=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['host'])" 2>/dev/null) + +echo "๐ŸŸข ${AGENTS:-?} agents ยท ${TASKS:-?} tasks" +echo "Colibri: ${HOST:-?} | socket: ${SOCKET} | agents: ${AGENTS:-?} | started tasks: ${TASKS:-?}" echo "xfce4-terminal --title 'Colibri Status' --command 'colibri status'"