feat: add cloud control-plane deployment entrypoints

This commit is contained in:
Codex
2026-03-23 13:24:08 +08:00
parent 47c29c723a
commit 3ff757e22d
6 changed files with 277 additions and 0 deletions

133
scripts/boss_chat.sh Executable file
View File

@@ -0,0 +1,133 @@
#!/usr/bin/env bash
set -euo pipefail
server_url="${BOSS_SERVER_URL:-http://127.0.0.1:43210}"
session_file="${BOSS_SESSION_FILE:-.boss-session}"
usage() {
cat <<'EOF'
Usage:
boss_chat.sh sessions
boss_chat.sh create [title]
boss_chat.sh send "<message>" [session_id]
boss_chat.sh status [session_id]
Environment:
BOSS_SERVER_URL Default: http://127.0.0.1:43210
BOSS_SESSION_FILE Default: .boss-session
EOF
}
require_tools() {
command -v curl >/dev/null 2>&1 || {
echo "curl is required" >&2
exit 1
}
command -v node >/dev/null 2>&1 || {
echo "node is required" >&2
exit 1
}
}
request() {
local method="$1"
local path="$2"
local body="${3:-}"
if [[ -n "$body" ]]; then
curl -fsS -X "$method" "$server_url$path" -H 'Content-Type: application/json' -d "$body"
else
curl -fsS -X "$method" "$server_url$path"
fi
}
json_payload() {
local key="$1"
local value="$2"
node -e 'const [key, value] = process.argv.slice(1); process.stdout.write(JSON.stringify({ [key]: value }));' "$key" "$value"
}
json_message_payload() {
local value="$1"
node -e 'const value = process.argv[1]; process.stdout.write(JSON.stringify({ content: value, channel: "cli" }));' "$value"
}
json_get() {
local expr="$1"
node -e "const fs = require('fs'); const data = JSON.parse(fs.readFileSync(0, 'utf8')); const result = (${expr}); if (result === undefined || result === null) process.exit(2); if (typeof result === 'string') process.stdout.write(result); else process.stdout.write(JSON.stringify(result, null, 2));"
}
save_session_id() {
printf '%s' "$1" > "$session_file"
}
load_session_id() {
if [[ -f "$session_file" ]]; then
cat "$session_file"
return 0
fi
return 1
}
create_session() {
local title="${1:-Boss 主控对话}"
local payload
payload="$(request POST /api/sessions "$(json_payload title "$title")")"
local session_id
session_id="$(printf '%s' "$payload" | json_get "data.session.id")"
save_session_id "$session_id"
printf '%s\n' "$payload"
}
command="${1:-}"
shift || true
if [[ -z "$command" ]]; then
usage
exit 1
fi
require_tools
case "$command" in
sessions)
request GET /api/sessions | node -e 'const fs=require("fs"); const data=JSON.parse(fs.readFileSync(0,"utf8")); for (const session of data) console.log(`${session.id}\t${session.status}\t${session.title}`);'
;;
create)
create_session "${1:-Boss 主控对话}"
;;
send)
message="${1:-}"
if [[ -z "$message" ]]; then
echo "Missing message." >&2
exit 1
fi
session_id="${2:-}"
if [[ -z "$session_id" ]]; then
session_id="$(load_session_id || true)"
fi
if [[ -z "$session_id" ]]; then
session_json="$(create_session "Boss 主控对话")"
session_id="$(printf '%s' "$session_json" | json_get "data.session.id")"
fi
request POST "/api/sessions/$session_id/messages" "$(json_message_payload "$message")"
printf '\n'
save_session_id "$session_id"
;;
status)
session_id="${1:-}"
if [[ -z "$session_id" ]]; then
session_id="$(load_session_id || true)"
fi
if [[ -z "$session_id" ]]; then
echo "No session id found. Run create or send first." >&2
exit 1
fi
request GET "/api/sessions/$session_id"
printf '\n'
;;
*)
usage
exit 1
;;
esac

11
scripts/boss_cloud_logs.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -euo pipefail
remote_dir="${BOSS_REMOTE_DIR:-/home/ubuntu/boss}"
tail_lines="${1:-150}"
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export AG_SERVER_SKILL="${AG_SERVER_SKILL:-$CODEX_HOME/skills/ai-glasses-server-debug}"
export AG_SERVER="${AG_SERVER:-$AG_SERVER_SKILL/scripts/server_ssh.sh}"
"$AG_SERVER" exec "set -euo pipefail; cd $(printf '%q' "$remote_dir"); sudo docker compose -f compose.cloud.yaml -p boss logs --tail $(printf '%q' "$tail_lines")"

10
scripts/boss_cloud_status.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail
remote_dir="${BOSS_REMOTE_DIR:-/home/ubuntu/boss}"
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export AG_SERVER_SKILL="${AG_SERVER_SKILL:-$CODEX_HOME/skills/ai-glasses-server-debug}"
export AG_SERVER="${AG_SERVER:-$AG_SERVER_SKILL/scripts/server_ssh.sh}"
"$AG_SERVER" exec "set -euo pipefail; cd $(printf '%q' "$remote_dir"); sudo docker compose -f compose.cloud.yaml -p boss ps; echo '---'; curl -fsS http://127.0.0.1:43210/api/health"

View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -euo pipefail
branch="${1:-main}"
remote_dir="${BOSS_REMOTE_DIR:-/home/ubuntu/boss}"
remote_repo="${BOSS_REMOTE_REPO:-https://git.hyzq.site/krisolo/boss.git}"
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export AG_SERVER_SKILL="${AG_SERVER_SKILL:-$CODEX_HOME/skills/ai-glasses-server-debug}"
export AG_SERVER="${AG_SERVER:-$AG_SERVER_SKILL/scripts/server_ssh.sh}"
if [[ ! -x "$AG_SERVER" ]]; then
echo "AI Glasses server wrapper not found: $AG_SERVER" >&2
exit 1
fi
remote_script=$(cat <<EOF
set -euo pipefail
REMOTE_DIR=$(printf '%q' "$remote_dir")
REMOTE_REPO=$(printf '%q' "$remote_repo")
BRANCH=$(printf '%q' "$branch")
mkdir -p "\$REMOTE_DIR"
if [[ ! -d "\$REMOTE_DIR/.git" ]]; then
rm -rf "\$REMOTE_DIR"
git clone "\$REMOTE_REPO" "\$REMOTE_DIR"
fi
cd "\$REMOTE_DIR"
git fetch origin "\$BRANCH"
git checkout "\$BRANCH"
git reset --hard "origin/\$BRANCH"
sudo docker compose -f compose.cloud.yaml -p boss up -d --build --remove-orphans
echo "__BOSS_DEPLOY_OK__"
sudo docker compose -f compose.cloud.yaml -p boss ps
sleep 3
curl -fsS http://127.0.0.1:43210/api/health
EOF
)
payload="$(printf '%s' "$remote_script" | base64 | tr -d '\n')"
"$AG_SERVER" exec "set -euo pipefail; printf '%s' '$payload' | base64 -d | bash"