From 51d1129224262f751f44f2a8affc169dca664427 Mon Sep 17 00:00:00 2001 From: Sulthan Nauval Abdillah Date: Tue, 11 Aug 2026 07:16:37 +0000 Subject: [PATCH] feat(web-ui): explicit `copilot-web start` + LAN bind by default on airgapped installs - `copilot-web` now requires an explicit subcommand: `start` or `stop`. Bare `copilot-web` (and the old `up`) print the usage line and exit 2. - Bind address resolution: COPILOT_UI_HOST env > ~/.copilot/ui-host file > loopback. setup-airgapped.sh writes 0.0.0.0 to ui-host on first install (operator override survives re-installs), so an airgapped console is reachable at http://:3939 with no SSH tunnel. - Online installs (get.sh / setup.sh) keep the loopback-only default. - The start banner now prints the LAN URL when bound beyond loopback, and installers list `rantaiclaw setup login` before first console start. - Docs updated: README LAN section, QUICKSTART, installer next-steps. --- README.md | 35 +++++++++++++++++++------------- get.sh | 6 +++--- install.sh | 2 +- release/files/QUICKSTART.md | 5 +++-- release/files/setup-airgapped.sh | 12 ++++++++--- release/files/setup.sh | 4 ++-- web-ui.sh | 21 +++++++++++++------ 7 files changed, 54 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 32aeddb..9ff9326 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ a local model); only *how you get the software* differs. The prebuilt bundle is | Mode | Use it when | What it fetches | |---|---|---| -| **Online** | the machine has internet | binary + skills now; web console on first `copilot-web` | +| **Online** | the machine has internet | binary + skills now; web console on first `copilot-web start` | | **Airgapped** | no GitHub / npm / bun.sh access | nothing — the bundle is fully pre-packaged | | **From source** | other CPU/OS, or your own RantaiClaw build | this git repo | @@ -76,10 +76,10 @@ rantaiclaw setup **3 — Run it:** ```bash rantaiclaw chat # chat in the terminal -copilot-web # web console → http://localhost:3939 (first run fetches claw-ui, ~1 min) +copilot-web start # web console → http://localhost:3939 (first run fetches claw-ui, ~1 min) ``` -**Check it worked:** `rantaiclaw --version` prints a version, and `copilot-web` opens the console. +**Check it worked:** `rantaiclaw --version` prints a version, and `copilot-web start` opens the console. **Update later:** `copilot-update` refreshes everything (binary + skills + web console). ### Airgapped mode @@ -107,8 +107,9 @@ web console (it does not touch your config): **4 — Configure your LLM, then run.** `setup provider` sets just the LLM and needs no network: ```bash rantaiclaw setup provider # provider + key, offline +rantaiclaw setup login # console password — airgapped installs expose the console on the LAN rantaiclaw chat # chat in the terminal -copilot-web # web console → http://localhost:3939 (runs offline) +copilot-web start # web console → http://:3939 (runs offline) ``` > The full `rantaiclaw setup` also walks channels / MCP, and those sections need network — on a > fully offline host stick to `rantaiclaw setup provider`. @@ -180,11 +181,11 @@ is upstream [claw-ui](https://github.com/RantAI-dev/claw-ui), installed on deman `~/.copilot/web-ui` from a signed prebuilt release and served as a production build. ```bash -copilot-web # first run: fetch (~1 min) + start → http://localhost:3939 +copilot-web start # first run: fetch (~1 min) + start → http://localhost:3939 copilot-web stop # stop the console + gateway ``` -From a source checkout (before `copilot-web` is on your PATH) use `./web-ui.sh` — it's the same launcher. +From a source checkout (before `copilot-web` is on your PATH) use `./web-ui.sh start` — it's the same launcher. Notes: - First run downloads claw-ui; later runs start instantly. Airgapped installs serve the bundled @@ -194,18 +195,24 @@ Notes: ### Reach it from another machine (LAN) -By default the console binds to **loopback** (`127.0.0.1`) — only this machine can open it. That's -deliberate: the console has **full control of the agent**, so LAN access is explicit opt-in. On a -**trusted** network, expose it in two steps: +The bind address comes from, in order: `COPILOT_UI_HOST` env → `~/.copilot/ui-host` file → +loopback (`127.0.0.1`). + +- **Airgapped installs bind the LAN by default**: `setup-airgapped.sh` writes `0.0.0.0` to + `~/.copilot/ui-host`, so `copilot-web start` is reachable at `http://:3939` + from any machine on the network — no SSH tunnel. The console has **full control of the + agent**, so set a password first: `rantaiclaw setup login`. +- **Online installs stay loopback-only** — only this machine can open the console. Expose it + explicitly on a **trusted** network: ```bash -rantaiclaw setup login # 1. set a console username + password (do this FIRST) -COPILOT_UI_HOST=0.0.0.0 copilot-web # 2. bind all interfaces → http://:3939 +rantaiclaw setup login # 1. set a console username + password (do this FIRST) +COPILOT_UI_HOST=0.0.0.0 copilot-web start # 2. bind all interfaces → http://:3939 ``` -- **Permanent:** put `host = "0.0.0.0"` under `[ui]` in `~/.rantaiclaw/profiles/default/config.toml`; - then a plain `copilot-web` binds to the LAN too. -- **Don't want to expose it?** Leave the default and tunnel instead — from your laptop run +- **Permanent:** `echo 0.0.0.0 > ~/.copilot/ui-host` — then a plain `copilot-web start` binds the + LAN too. Back to loopback-only: `echo 127.0.0.1 > ~/.copilot/ui-host` (survives re-installs). +- **Don't want to expose it?** Keep loopback and tunnel instead — from your laptop run `ssh -L 3939:127.0.0.1:3939 @`, then open `http://localhost:3939`. ## What's in here diff --git a/get.sh b/get.sh index c9573e1..10a9f1b 100755 --- a/get.sh +++ b/get.sh @@ -107,7 +107,7 @@ done say "✓ skills deployed → $SK" # stage the web console launcher so the browser UI works WITHOUT a git clone. -# This is lazy: no heavy fetch here — the first `copilot-web` run clones claw-ui + installs deps. +# This is lazy: no heavy fetch here — the first `copilot-web start` clones claw-ui + installs deps. if [ -f "$BDIR/web-ui.sh" ]; then command -v git >/dev/null 2>&1 || say "! git not found — needed by the web console (copilot-web). Install git." CPDIR="$HOME/.copilot" @@ -137,7 +137,7 @@ UPD install -m755 "$BDIR/copilot-uninstall" "$CPDIR/copilot-uninstall" ln -sf "$CPDIR/copilot-uninstall" "$DEST/copilot-uninstall" fi - say "✓ web console ready → run: copilot-web" + say "✓ web console ready → run: copilot-web start" fi PATHHINT=""; case ":$PATH:" in *":$DEST:"*) ;; *) PATHHINT="export PATH=\"$DEST:\$PATH\"; ";; esac @@ -145,5 +145,5 @@ say "" say "Ready:" say " ${PATHHINT}rantaiclaw setup # set LLM provider/key (once)" say " rantaiclaw chat # CLI agent" -say " copilot-web # web console → http://localhost:3939" +say " copilot-web start # web console → http://localhost:3939" say " copilot-update # update everything later" diff --git a/install.sh b/install.sh index 18c9045..ccd902e 100755 --- a/install.sh +++ b/install.sh @@ -64,7 +64,7 @@ fi say "" say "Done. Next:" say " rantaiclaw setup # set your LLM provider + key (if you haven't)" -say " ./web-ui.sh # launch the web console → http://localhost:3939" +say " ./web-ui.sh start # launch the web console → http://localhost:3939" say "" say " # operate a Hypervisor cluster (after a kubeconfig is in the workspace):" say " rantaiclaw agent -m \"list all VMs on the Hypervisor cluster\"" diff --git a/release/files/QUICKSTART.md b/release/files/QUICKSTART.md index c172a3a..a271591 100644 --- a/release/files/QUICKSTART.md +++ b/release/files/QUICKSTART.md @@ -11,10 +11,11 @@ Use the installer that matches the bundle you have — **they are not interchang **Airgapped bundle** (`rantai-copilot-airgapped-*`) — for a host with no internet. This is the only installer that stages the prebuilt web console shipped inside the tarball. `setup.sh` does not, so -using it here leaves `copilot-web` trying to fetch claw-ui over a network you don't have: +using it here leaves `copilot-web start` trying to fetch claw-ui over a network you don't have: ```bash ./setup-airgapped.sh rantaiclaw setup provider # LLM provider + key — offline, needs no network +rantaiclaw setup login # console password — the airgapped console binds the LAN by default ``` **Online bundle** (`rantai-copilot-*`) — for a host that can reach GitHub: @@ -53,7 +54,7 @@ chmod 600 ~/.rantaiclaw/profiles/default/workspace/kubeconfig-hypervisor ## 3. Operate it ```bash -rantaiclaw chat # or: copilot-web → http://localhost:3939 +rantaiclaw chat # or: copilot-web start → http://:3939 (airgapped: LAN-reachable) ``` Ask in plain language: ``` diff --git a/release/files/setup-airgapped.sh b/release/files/setup-airgapped.sh index 9bb1533..6ab26a6 100755 --- a/release/files/setup-airgapped.sh +++ b/release/files/setup-airgapped.sh @@ -68,6 +68,11 @@ install -m755 "$HERE/web-ui.sh" "$CPDIR/.web-ui.sh.$$" && mv -f "$CPDIR/.web-ui. [ -f "$HERE/VERSION" ] && cp "$HERE/VERSION" "$CPDIR/VERSION" chmod +x "$CPDIR/web-ui.sh" ln -sf "$CPDIR/web-ui.sh" "$DEST/copilot-web" +# Airgapped default: console reachable over the LAN (the operator's browser is rarely +# on the server itself). Operator override survives re-install — to go back to +# loopback-only: echo 127.0.0.1 > ~/.copilot/ui-host (or per-run COPILOT_UI_HOST). +# The console has full agent control: set a password first (rantaiclaw setup login). +[ -f "$CPDIR/ui-host" ] || printf '0.0.0.0\n' > "$CPDIR/ui-host" if [ -f "$HERE/copilot-uninstall" ]; then install -m755 "$HERE/copilot-uninstall" "$CPDIR/copilot-uninstall" ln -sf "$CPDIR/copilot-uninstall" "$DEST/copilot-uninstall" @@ -75,9 +80,9 @@ fi if [ -f "$HERE/web-ui/server.js" ] && [ -d "$HERE/web-ui/node_modules" ]; then rm -rf "$CPDIR/web-ui"; cp -r "$HERE/web-ui" "$CPDIR/web-ui" : > "$CPDIR/offline" # marker → copilot-web runs offline (skips fetch) - say "✓ web console (prebuilt, offline) → run: copilot-web" + say "✓ web console (prebuilt, offline) → run: copilot-web start" else - say "! web console prebuilt files missing — copilot-web will need network to fetch claw-ui" + say "! web console prebuilt files missing — copilot-web start will need network to fetch claw-ui" fi # 6. an airgapped `copilot-update` that explains the offline update flow (no network fetch) @@ -99,6 +104,7 @@ say "✓ copilot-update → prints the offline update steps" say "" say "Done (airgapped). Next:" say " rantaiclaw setup provider # set your LLM provider + key (offline, LLM only)" +say " rantaiclaw setup login # console password — the console binds the LAN by default here" say " rantaiclaw chat # CLI agent" -say " copilot-web # web console → http://localhost:3939 (offline)" +say " copilot-web start # web console → http://:3939 (offline)" say " # updates: bring a newer rantai-copilot-airgapped bundle, re-run ./setup-airgapped.sh" diff --git a/release/files/setup.sh b/release/files/setup.sh index 308fc71..2108702 100755 --- a/release/files/setup.sh +++ b/release/files/setup.sh @@ -78,14 +78,14 @@ if [ -f "$HERE/web-ui.sh" ]; then install -m755 "$HERE/copilot-uninstall" "$CPDIR/copilot-uninstall" ln -sf "$CPDIR/copilot-uninstall" "$DEST/copilot-uninstall" fi - say "✓ web console staged → run: copilot-web" + say "✓ web console staged → run: copilot-web start" fi cat < ~/.copilot/ui-host (written by the airgapped +# installer, LAN default) > empty (rantaiclaw's loopback default). e.g. 0.0.0.0 to +# reach the console from your LAN — enable a login first (see README). +HOST="${COPILOT_UI_HOST:-$(cat "$HOME/.copilot/ui-host" 2>/dev/null || true)}" VERBOSE="${COPILOT_VERBOSE:-0}" OFFLINE="${COPILOT_OFFLINE:-0}" # airgapped: skip the online fetch, use a pre-provisioned $UIDIR [ "$OFFLINE" != 1 ] && [ -f "$HOME/.copilot/offline" ] && OFFLINE=1 # marker dropped by setup-airgapped.sh @@ -28,7 +31,7 @@ warn() { printf '⚠ %s\n' "$*" >&2; } q() { if [ "$VERBOSE" = 1 ]; then "$@"; else "$@" >>"$LOG" 2>&1; fi; } port_busy() { (exec 3<>"/dev/tcp/127.0.0.1/$1") 2>/dev/null && { exec 3>&- 3<&-; return 0; }; return 1; } -case "${1:-up}" in +case "${1:-}" in # `rantaiclaw ui stop` exits 0 whether or not anything was running, so its exit # code cannot tell the two apart — an unconditional "✓ stopped" is what an # operator reads right before pulling the console's files out from under it. @@ -45,8 +48,9 @@ case "${1:-up}" in fi say "✓ stopped" exit 0 ;; - up|"") ;; - *) say "usage: $0 [up|stop]"; exit 2 ;; + start) ;; + # bare `copilot-web` used to mean start; now explicit — old habit gets the usage line + *) say "usage: copilot-web start|stop"; exit 2 ;; esac command -v rantaiclaw >/dev/null 2>&1 || { warn "rantaiclaw not on PATH — open a new terminal"; exit 1; } @@ -95,4 +99,9 @@ if [ -n "$HOST" ] && [ "$HOST" != 127.0.0.1 ] && [ "$HOST" != localhost ]; then warn "binding to $HOST — the console (full agent control) will be reachable on your LAN; set a login first: rantaiclaw setup login" fi q rantaiclaw ui start --dir "$UIDIR" --port "$PORT" ${HOST:+--host "$HOST"} || { warn "start failed — see $LOG"; exit 1; } -say "✓ RantAI Copilot console → http://localhost:$PORT (stop: copilot-web stop)" +if [ -n "$HOST" ] && [ "$HOST" != 127.0.0.1 ] && [ "$HOST" != localhost ]; then + IP="$(hostname -I 2>/dev/null | awk '{print $1}')" + say "✓ RantAI Copilot console → http://${IP:-}:$PORT (LAN · stop: copilot-web stop)" +else + say "✓ RantAI Copilot console → http://localhost:$PORT (stop: copilot-web stop)" +fi