Last active
August 17, 2026 08:03
-
-
Save kulapoo/11d3412987e2f4cf95ea283a5fdc99bf to your computer and use it in GitHub Desktop.
A single-file bash CLI (uad) that launches the knowledge-graph dashboard of Understand-Anything (https://github.com/Egonex-AI/Understand-Anything) (an AI-plugin that codebases into interactive knowledge graphs) for any project that has run its /understand analysis. Requires the plugin installed at ~/.understand-anything-plugin (or set UAD_PLUGIN…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # uad — understand-anything dashboard launcher. | |
| # | |
| # Usage: | |
| # uad [path] [--open] Start the dashboard for the project at <path> | |
| # (default: .). Prints the access URL; --open also | |
| # opens it in your browser. | |
| # uad stop Stop any running instance. | |
| # uad status Show whether the dashboard is running (and its URL). | |
| # uad url Print the current dashboard URL. | |
| # uad open Open the current dashboard URL in your browser. | |
| # | |
| # Environment: | |
| # UAD_PORT Port to serve on (default: 9627). | |
| # UAD_PLUGIN_ROOT Plugin install root (default: ~/.understand-anything-plugin). | |
| set -euo pipefail | |
| PORT="${UAD_PORT:-9627}" | |
| PLUGIN_ROOT="${UAD_PLUGIN_ROOT:-$HOME/.understand-anything-plugin}" | |
| DASH_DIR="$PLUGIN_ROOT/packages/dashboard" | |
| STATE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/understand-anything" | |
| PIDFILE="$STATE_DIR/uad.pid" | |
| URLFILE="$STATE_DIR/uad.url" | |
| die() { echo "uad: $*" >&2; exit 1; } | |
| usage() { | |
| sed -n '2,17p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//' | |
| } | |
| is_running() { | |
| [ -f "$PIDFILE" ] || return 1 | |
| local pid | |
| pid="$(cat "$PIDFILE" 2>/dev/null)" || return 1 | |
| [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null | |
| } | |
| pid_from_file() { cat "$PIDFILE" 2>/dev/null || true; } | |
| # Open a URL in the default browser (macOS: open, Linux: xdg-open/wslview). | |
| # Runs detached so a misbehaving opener can never block the dashboard. | |
| open_browser() { | |
| local url="$1" | |
| case "$(uname -s)" in | |
| Darwin) open "$url" >/dev/null 2>&1 & ;; | |
| *) | |
| if command -v xdg-open >/dev/null 2>&1; then | |
| xdg-open "$url" >/dev/null 2>&1 & | |
| elif command -v wslview >/dev/null 2>&1; then | |
| wslview "$url" >/dev/null 2>&1 & | |
| else | |
| echo "uad: no browser opener found (xdg-open/open); open manually: $url" >&2 | |
| fi | |
| ;; | |
| esac | |
| } | |
| # Kill whatever listens on $PORT. Uses fuser (Linux) or lsof (macOS). | |
| free_port() { | |
| if command -v fuser >/dev/null 2>&1; then | |
| fuser -k "$PORT/tcp" >/dev/null 2>&1 || true | |
| elif command -v lsof >/dev/null 2>&1; then | |
| local pids | |
| pids="$(lsof -ti tcp:"$PORT" 2>/dev/null || true)" | |
| [ -n "$pids" ] && kill $pids 2>/dev/null || true | |
| fi | |
| } | |
| is_port_busy() { | |
| if command -v fuser >/dev/null 2>&1; then | |
| fuser "$PORT/tcp" >/dev/null 2>&1 | |
| elif command -v lsof >/dev/null 2>&1; then | |
| [ -n "$(lsof -ti tcp:"$PORT" 2>/dev/null || true)" ] | |
| else | |
| return 1 | |
| fi | |
| } | |
| cmd_status() { | |
| if is_running; then | |
| echo "running (pid $(pid_from_file), port $PORT)" | |
| [ -s "$URLFILE" ] && echo "url: $(cat "$URLFILE")" | |
| else | |
| rm -f "$PIDFILE" "$URLFILE" 2>/dev/null || true | |
| if is_port_busy; then | |
| echo "not running, but port $PORT is occupied by another process" | |
| else | |
| echo "not running" | |
| fi | |
| fi | |
| } | |
| cmd_stop() { | |
| local stopped=0 | |
| if is_running; then | |
| local pid | |
| pid="$(pid_from_file)" | |
| kill "$pid" 2>/dev/null || true | |
| for _ in $(seq 1 50); do | |
| kill -0 "$pid" 2>/dev/null || break | |
| sleep 0.1 | |
| done | |
| kill -9 "$pid" 2>/dev/null || true | |
| stopped=1 | |
| fi | |
| rm -f "$PIDFILE" "$URLFILE" 2>/dev/null || true | |
| free_port | |
| if [ "$stopped" -eq 1 ]; then | |
| echo "stopped" | |
| else | |
| echo "not running" | |
| fi | |
| } | |
| cmd_url() { | |
| is_running || die "not running (start with: uad [path])" | |
| [ -s "$URLFILE" ] || die "no URL recorded" | |
| cat "$URLFILE" | |
| } | |
| cmd_open() { | |
| is_running || die "not running (start with: uad [path])" | |
| [ -s "$URLFILE" ] || die "no URL recorded" | |
| open_browser "$(cat "$URLFILE")" | |
| echo "uad: opened $(cat "$URLFILE")" | |
| } | |
| bootstrap() { | |
| [ -d "$DASH_DIR" ] || die "plugin not found at $PLUGIN_ROOT (set UAD_PLUGIN_ROOT to override)" | |
| if [ ! -d "$DASH_DIR/node_modules" ]; then | |
| echo "uad: installing dashboard dependencies (first run)..." | |
| (cd "$DASH_DIR" && (pnpm install --frozen-lockfile 2>/dev/null || pnpm install)) | |
| fi | |
| if [ ! -f "$PLUGIN_ROOT/packages/core/dist/schema.js" ]; then | |
| echo "uad: building @understand-anything/core (first run)..." | |
| (cd "$PLUGIN_ROOT" && pnpm --filter @understand-anything/core build) | |
| fi | |
| } | |
| cmd_start() { | |
| local target="." want_open=0 | |
| while [ $# -gt 0 ]; do | |
| case "$1" in | |
| --open) want_open=1 ;; | |
| -*) usage; die "unknown option: $1" ;; | |
| *) target="$1" ;; | |
| esac | |
| shift | |
| done | |
| local abs | |
| abs="$(realpath "$target" 2>/dev/null || readlink -f "$target" 2>/dev/null || true)" | |
| [ -n "$abs" ] || die "cannot resolve path: $target" | |
| [ -d "$abs" ] || die "not a directory: $abs" | |
| [ -f "$abs/.understand-anything/knowledge-graph.json" ] || | |
| die "no knowledge graph at $abs/.understand-anything/knowledge-graph.json — run /understand first" | |
| if is_running; then | |
| echo "uad: stopping previous instance (pid $(pid_from_file))" | |
| cmd_stop >/dev/null | |
| else | |
| rm -f "$PIDFILE" "$URLFILE" 2>/dev/null || true | |
| fi | |
| free_port | |
| bootstrap | |
| mkdir -p "$STATE_DIR" | |
| # We pick the token ourselves (vite.config.ts honours UNDERSTAND_ACCESS_TOKEN) | |
| # so the URL is known up-front, and disable vite's own auto-open via BROWSER=none. | |
| # The token is PERSISTED and reused across runs: the dashboard caches it in | |
| # sessionStorage (and strips it from the URL), so a fresh token per run would | |
| # 403 old tabs into "Invalid knowledge graph" errors. | |
| local tokenfile="$STATE_DIR/uad.token" | |
| local token url | |
| if [ -s "$tokenfile" ] && [ "$(wc -c < "$tokenfile")" -eq 32 ]; then | |
| token="$(cat "$tokenfile")" | |
| else | |
| token="$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')" | |
| printf '%s' "$token" > "$tokenfile" | |
| chmod 600 "$tokenfile" | |
| fi | |
| url="http://127.0.0.1:$PORT/?token=$token" | |
| local vite_pid="" | |
| cleanup() { | |
| if [ -n "$vite_pid" ]; then | |
| kill "$vite_pid" 2>/dev/null || true | |
| fi | |
| if [ -f "$PIDFILE" ] && [ "$(pid_from_file)" = "$$" ]; then | |
| rm -f "$PIDFILE" | |
| fi | |
| rm -f "$URLFILE" 2>/dev/null || true | |
| } | |
| trap cleanup INT TERM HUP EXIT | |
| echo "$$" > "$PIDFILE" | |
| echo "$url" > "$URLFILE" | |
| echo "uad: serving $abs — Ctrl+C to stop" | |
| echo "uad: starting dashboard..." | |
| cd "$DASH_DIR" | |
| BROWSER=none UNDERSTAND_ACCESS_TOKEN="$token" GRAPH_DIR="$abs" npx vite --host 127.0.0.1 --port "$PORT" --strictPort & | |
| vite_pid=$! | |
| # Wait until the server actually answers before advertising the URL. | |
| # (npx spawn can take seconds cold; handing out a dead URL reads as failure.) | |
| local ready=0 | |
| for _ in $(seq 1 150); do # up to 15s | |
| if ! kill -0 "$vite_pid" 2>/dev/null; then | |
| echo | |
| echo "uad: ERROR — the dashboard server exited during startup." >&2 | |
| echo "uad: common cause: port $PORT is in use (check: ss -ltn 'sport = :$PORT')." >&2 | |
| echo "uad: server output is above; if empty, rerun with: (cd $DASH_DIR && npx vite --host 127.0.0.1 --port $PORT)" >&2 | |
| exit 1 | |
| fi | |
| if (exec 3<>"/dev/tcp/127.0.0.1/$PORT") 2>/dev/null; then | |
| ready=1 | |
| break | |
| fi | |
| sleep 0.1 | |
| done | |
| if [ "$ready" -ne 1 ]; then | |
| echo "uad: WARNING — server not answering on port $PORT after 15s; it may still be starting." >&2 | |
| fi | |
| # URL on its own bare line so terminal copy-paste can't mangle it. | |
| echo | |
| echo "===================================================================" | |
| echo "Dashboard ready: $url" | |
| echo "===================================================================" | |
| echo " copy the URL above into any browser — it stays valid while uad runs" | |
| echo " (or run: uad open)" | |
| echo | |
| if [ "$want_open" -eq 1 ]; then | |
| open_browser "$url" | |
| fi | |
| wait "$vite_pid" || true | |
| } | |
| case "${1:-}" in | |
| stop) cmd_stop ;; | |
| status) cmd_status ;; | |
| url) cmd_url ;; | |
| open) cmd_open ;; | |
| -h|--help|help) usage ;; | |
| *) cmd_start "$@" ;; | |
| esac |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
uad — CLI launcher for the Understand-Anything dashboard