Initial commit: AetherForge Linux (forge-mesh) v0.1.0-dev
Some checks failed
Test / test (push) Has been cancelled
Some checks failed
Test / test (push) Has been cancelled
This commit is contained in:
109
scripts/LAUNCH.sh
Executable file
109
scripts/LAUNCH.sh
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bash
|
||||
# Portable AetherForge / forge-mesh command deck launcher (USB edition).
|
||||
# Starts optional cloudflared sidecar, sets AF_TUNNEL_EXTERNAL=1, opens the deck UI,
|
||||
# and runs forge-mesh-server against ./data.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [[ "$(basename "$SCRIPT_DIR")" == "scripts" ]]; then
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
else
|
||||
ROOT="$SCRIPT_DIR"
|
||||
fi
|
||||
cd "$ROOT"
|
||||
|
||||
DATA_DIR="${AF_DATA_DIR:-$ROOT/data}"
|
||||
CONFIG="${AF_CONFIG:-$DATA_DIR/config.json}"
|
||||
SERVER_BIN="${AF_SERVER_BIN:-$ROOT/bin/forge-mesh-server}"
|
||||
DECK_URL="${AF_DECK_URL:-http://localhost:8989}"
|
||||
CLOUDFLARED_PID=""
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "$CLOUDFLARED_PID" ]] && kill -0 "$CLOUDFLARED_PID" 2>/dev/null; then
|
||||
kill "$CLOUDFLARED_PID" 2>/dev/null || true
|
||||
wait "$CLOUDFLARED_PID" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
resolve_cloudflared() {
|
||||
if command -v cloudflared >/dev/null 2>&1; then
|
||||
command -v cloudflared
|
||||
return 0
|
||||
fi
|
||||
for candidate in "$ROOT/bin/cloudflared" "$ROOT/cloudflared"; do
|
||||
if [[ -x "$candidate" ]]; then
|
||||
echo "$candidate"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
read_tunnel_token() {
|
||||
if [[ -n "${AF_TUNNEL_TOKEN:-}" ]]; then
|
||||
printf '%s' "$AF_TUNNEL_TOKEN"
|
||||
return 0
|
||||
fi
|
||||
local token_file="$DATA_DIR/cloudflared-token.txt"
|
||||
if [[ -f "$token_file" ]]; then
|
||||
tr -d '[:space:]' <"$token_file"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
start_tunnel_sidecar() {
|
||||
local token cf_bin
|
||||
token="$(read_tunnel_token)" || return 0
|
||||
cf_bin="$(resolve_cloudflared)" || {
|
||||
echo "WARN: tunnel token present but cloudflared not found (PATH or $ROOT/bin/cloudflared)" >&2
|
||||
return 0
|
||||
}
|
||||
|
||||
echo "Starting cloudflared sidecar..."
|
||||
"$cf_bin" tunnel --no-autoupdate run --token "$token" &
|
||||
CLOUDFLARED_PID=$!
|
||||
export AF_TUNNEL_EXTERNAL=1
|
||||
echo "AF_TUNNEL_EXTERNAL=1 (cloudflared pid $CLOUDFLARED_PID)"
|
||||
}
|
||||
|
||||
open_browser() {
|
||||
local url="$1"
|
||||
if [[ -n "${AF_NO_BROWSER:-}" ]]; then
|
||||
echo "AF_NO_BROWSER set; deck at $url"
|
||||
return 0
|
||||
fi
|
||||
for opener in xdg-open sensible-browser x-www-browser gnome-open kde-open; do
|
||||
if command -v "$opener" >/dev/null 2>&1; then
|
||||
"$opener" "$url" >/dev/null 2>&1 &
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "Open your browser to $url"
|
||||
}
|
||||
|
||||
ensure_server_binary() {
|
||||
if [[ -x "$SERVER_BIN" ]]; then
|
||||
return 0
|
||||
fi
|
||||
if command -v forge-mesh-server >/dev/null 2>&1; then
|
||||
SERVER_BIN="$(command -v forge-mesh-server)"
|
||||
return 0
|
||||
fi
|
||||
echo "ERROR: forge-mesh-server not found. Build with 'make server' or place binary in $ROOT/bin/" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
mkdir -p "$DATA_DIR"
|
||||
if [[ ! -f "$CONFIG" ]]; then
|
||||
echo "ERROR: missing config at $CONFIG" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
start_tunnel_sidecar
|
||||
ensure_server_binary
|
||||
|
||||
open_browser "$DECK_URL"
|
||||
echo "Starting forge-mesh-server (config: $CONFIG)"
|
||||
exec "$SERVER_BIN" -config "$CONFIG"
|
||||
Reference in New Issue
Block a user