#!/usr/bin/env bash # # visionA Agent 本地啟動腳本(公網正式路徑 demo 驗證用) # # 用途:在本機起 agent GUI,走公網邊界反代(stage-9527.innovedus.com:9527) # 連 tunnel,驗證「網管開通邊界反代 WS 轉發」是否生效 + 雲端 device online 顯示。 # # ⚠️ 實測重點:Wails app 不能用 `go run .`(會 panic: missing build tags)。 # 必須先用 `make wails-macos` build 成 .app(需先裝 wails CLI),本腳本直接開 .app。 # 這個腳本只設環境變數 + 開既有 build 好的 .app,不改任何 agent 原始碼。 # # 前置(首次): # go install github.com/wailsapp/wails/v2/cmd/wails@latest # cd local-agent && make wails-macos # # 用法: # ./start-agent.sh # 走公網正式路徑(預設) # ./start-agent.sh internal # 走內網 demo 路徑(ws://192.168.0.130:9527,需 VPN) # # 起來後:在 GUI 配對頁貼上瀏覽器拿到的配對碼(vAc_ 開頭),狀態頁看 online。 set -euo pipefail # ── 腳本所在目錄(讓從任何地方呼叫都能定位 agent)── SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" APP="$SCRIPT_DIR/visiona-agent/build/bin/visiona-agent.app" APP_BIN="$APP/Contents/MacOS/visiona-agent" # ── 選路徑:public(預設,公網正式)/ internal(內網 demo)── MODE="${1:-public}" case "$MODE" in public) HOST="stage-9527.innovedus.com:9527" CLOUD_API_URL="https://$HOST" RELAY_URL="wss://$HOST/tunnel/connect" WS_SCHEME="https" ;; internal) HOST="192.168.0.130:9527" CLOUD_API_URL="http://$HOST" RELAY_URL="ws://$HOST/tunnel/connect" WS_SCHEME="http" ;; *) echo "用法:$0 [public|internal]" >&2 echo " public = 公網正式路徑 wss://stage-9527.innovedus.com:9527(預設)" >&2 echo " internal = 內網 demo 路徑 ws://192.168.0.130:9527(需 VPN)" >&2 exit 1 ;; esac echo "════════════════════════════════════════════════════════" echo " visionA Agent 啟動($MODE 路徑)" echo "════════════════════════════════════════════════════════" echo " Cloud API : $CLOUD_API_URL" echo " Relay URL : $RELAY_URL" echo "" # ── 前置檢查:.app 存在嗎?── if [ ! -x "$APP_BIN" ]; then echo "❌ 找不到 build 好的 app:$APP_BIN" >&2 echo " 請先 build(首次):" >&2 echo " go install github.com/wailsapp/wails/v2/cmd/wails@latest" >&2 echo " cd \"$SCRIPT_DIR\" && PATH=\"\$(go env GOPATH)/bin:\$PATH\" make wails-macos" >&2 exit 1 fi # ──────────────────────────────────────────────────────────── # 預檢:開 GUI 前先測邊界反代 WS 握手(省得白貼配對碼) # 回 101 = WS 轉發通;400 = 邊界反代還在剝 header(網管沒設對); # 444 = Host 沒帶對;逾時 = 防火牆/DNS。 # ──────────────────────────────────────────────────────────── echo "──▶ 預檢:測 $HOST 的 WS 握手 ..." # https(stage 自簽憑證)時帶 -k:預檢只測可達性,不驗憑證; # 否則 TLS 握手直接失敗回 000,被誤判成「防火牆/DNS 問題」誤導排查。 CURL_INSECURE="" if [ "$WS_SCHEME" = "https" ]; then CURL_INSECURE="-k" fi WS_CODE="$(curl -s $CURL_INSECURE -o /dev/null -w '%{http_code}' -m 10 -N \ -H 'Connection: Upgrade' \ -H 'Upgrade: websocket' \ -H 'Sec-WebSocket-Version: 13' \ -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \ "$WS_SCHEME://$HOST/tunnel/connect" 2>/dev/null || echo "000")" case "$WS_CODE" in 101) echo " ✅ 101 — 邊界反代 WS 轉發已生效,tunnel 可通。" ;; 401) echo " ✅ 401(WS header 有過、卡在 token 驗證)— WS 轉發 OK,屬正常(配對後帶 token)。" ;; 400) echo " ❌ 400 — 邊界反代還在剝 WS upgrade header(唯一根因未解)。" echo " → 請網管在公網入口 proxy 開 WS 轉發(h1.1 + Upgrade/Connection header)。" echo " 5 秒後仍會續開 GUI(Ctrl-C 中止)。"; sleep 5 ;; 444) echo " ⚠️ 444 — Host 白名單擋掉(邊界反代沒帶對 Host: ${HOST})。5 秒後續開(Ctrl-C 中止)。"; sleep 5 ;; 000) echo " ⚠️ 連線逾時/拒絕 — 防火牆沒放行 :9527 或 DNS 解錯(internal 請確認 VPN)。" echo " 5 秒後續開(Ctrl-C 中止)。"; sleep 5 ;; *) echo " ⚠️ 收到 HTTP ${WS_CODE}(非預期)。5 秒後續開(Ctrl-C 中止)。"; sleep 5 ;; esac echo "" # ── 設環境變數(優先級:env > config.yaml > 內建預設)── export VISIONA_CLOUD_API_URL="$CLOUD_API_URL" export VISIONA_RELAY_URL="$RELAY_URL" # public 模式:stage 用自簽憑證,agent 需明確 opt-in 跳過 TLS 驗證 # (pairing exchange + tunnel WSS + 設定頁「測試連線」三條路徑共用此開關), # 否則全部 x509 失敗,與本腳本的 demo 目的自相矛盾。 # ⚠️ DEV / DEMO ONLY — 正式環境絕不可設此變數。 if [ "$MODE" = "public" ]; then export VISIONA_INSECURE_SKIP_TLS_VERIFY=true echo "⚠️ 已設 VISIONA_INSECURE_SKIP_TLS_VERIFY=true(stage 自簽憑證用;跳過 TLS 驗證,僅 demo 用)" echo "" fi # ── 直接執行 .app 內的 binary(保留 stdout/stderr 在終端看 log;env 有帶進去)── echo "──▶ 啟動 GUI(${APP_BIN})..." echo " 起來後:配對頁貼上瀏覽器拿到的配對碼(vAc_ 開頭)→ 狀態頁看 online。" echo " (關 GUI 視窗即結束 agent)" echo "" exec "$APP_BIN"