#!/bin/bash # deploy.sh — AgentOS 一键部署脚本 # 其他机器在 git pull 后运行此脚本,即可同步本机所有变更 # 用法: bash 00_bootstrap/deploy.sh # 目标: 在其他机器上运行一次,环境变量 → 本地配置 → 依赖检查 → 全部就绪 set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" AGENT_SYNC="$(cd "$SCRIPT_DIR/.." && pwd)" info() { echo -e "\033[36m[INFO]\033[0m $1"; } ok() { echo -e "\033[32m[OK]\033[0m $1"; } warn() { echo -e "\033[33m[WARN]\033[0m $1"; } err() { echo -e "\033[31m[ERROR]\033[0m $1"; } echo "============================================" echo " AgentOS 一键部署脚本" echo " 仓库: $AGENT_SYNC" echo " 时间: $(date '+%Y-%m-%d %H:%M')" echo "============================================" # ── 步骤1: 设置环境变量 AGENT_SYNC / AGENT_LOCAL ── echo "" info "步骤1/5: 设置环境变量..." if [ -z "$AGENT_SYNC" ]; then export AGENT_SYNC="$AGENT_SYNC" fi if [ -z "$AGENT_LOCAL" ]; then export AGENT_LOCAL="$HOME/workbuddy-agent-os/agent-local" fi # 写入 .zshrc for RC_FILE in "$HOME/.zshrc" "$HOME/.bash_profile"; do if [ -f "$RC_FILE" ]; then if ! grep -q "export AGENT_SYNC" "$RC_FILE" 2>/dev/null; then echo "" >> "$RC_FILE" echo "# AgentOS 路径变量(由 deploy.sh 自动添加)" >> "$RC_FILE" echo "export AGENT_SYNC=\"$AGENT_SYNC\"" >> "$RC_FILE" echo "export AGENT_LOCAL=\"$AGENT_LOCAL\"" >> "$RC_FILE" ok "已写入 $RC_FILE" else ok "$RC_FILE 已有 AGENT_SYNC 设置" fi break fi done # ── 步骤2: 创建 agent-local 目录结构 ── echo "" info "步骤2/5: 创建本机目录结构..." mkdir -p "$AGENT_LOCAL/identity" mkdir -p "$AGENT_LOCAL/memory/raw" mkdir -p "$AGENT_LOCAL/memory/vector_db" mkdir -p "$AGENT_LOCAL/memory/daily" mkdir -p "$AGENT_LOCAL/runtime/cache" mkdir -p "$AGENT_LOCAL/tools/matrix/config" mkdir -p "$AGENT_LOCAL/tools/matrix/identities" mkdir -p "$AGENT_LOCAL/tools/matrix/data" ok "目录结构已创建" # ── 步骤3: 创建本地配置(如不存在)── echo "" info "步骤3/5: 配置本地参数..." LOCAL_CONFIG="$AGENT_LOCAL/config.yaml" if [ ! -f "$LOCAL_CONFIG" ]; then HOST="$(hostname)" cat > "$LOCAL_CONFIG" << CONFEOF # agent-local/config.yaml — 本机唯一配置入口 # 此文件每台机器独立,不同步到 Git。覆盖 ORACLE.yaml 中的默认值。 hostname: "$HOST" machine_uid: "" # 代理设置(各机器不同) proxy: socks5: "socks5://127.0.0.1:10800" # 端口分配 ports: dashboard: 9988 camouflage_base: 9200 CONFEOF ok "已创建: $LOCAL_CONFIG" else ok "本地配置已存在: $LOCAL_CONFIG" fi # ── 步骤4: 检查 Python 和依赖 ── echo "" info "步骤4/5: 检查运行环境..." PYTHON_OK=false for py in "$AGENT_LOCAL/../.workbuddy/binaries/python/envs/agent-os/bin/python3" \ "$HOME/.workbuddy/binaries/python/envs/agent-os/bin/python3" \ "/Users/chengzige/.workbuddy/binaries/python/envs/agent-os/bin/python3" \ "/usr/local/bin/python3" "/usr/bin/python3"; do if [ -x "$py" ]; then VER=$("$py" --version 2>&1) info "Python: $VER ($py)" PYTHON_OK=true break fi done if [ "$PYTHON_OK" = false ]; then warn "未找到可用的 Python 3。请先安装 WorkBuddy 或 Python 3.13+" fi # 检查关键依赖 if [ "$PYTHON_OK" = true ]; then # 找可用的 pip for py in "$HOME/.workbuddy/binaries/python/envs/agent-os/bin/pip3" \ "$HOME/.workbuddy/binaries/python/versions/3.13.12/bin/pip3" \ "pip3"; do if command -v "$py" &>/dev/null; then PIP="$py" break fi done fi # ── 步骤5: 检查 Tailscale(远程连接)── echo "" info "步骤5/6: 检查远程连接..." if command -v tailscale &>/dev/null; then TS_STATUS=$(tailscale status 2>/dev/null | head -3) if [ -n "$TS_STATUS" ]; then ok "Tailscale 已连接" echo "$TS_STATUS" | while read line; do echo " $line"; done else warn "Tailscale 已安装但未登录,请运行: tailscale up" fi else warn "Tailscale 未安装。远程连接需要 Tailscale 实现跨局域网通信。" warn "安装方法: brew install --cask tailscale 或从 https://tailscale.com/download 下载" echo "" fi # ── 步骤6: 检查 Python 代码签名(新增:解决 macOS 代码签名问题)── echo "" info "步骤6/7: 检查 Python 代码签名..." # 找到 WorkBuddy 管理的 Python for PY_BIN in "$HOME/.workbuddy/binaries/python/versions/3.13.12/bin/python3" \ "$HOME/.workbuddy/binaries/python/versions/"*/bin/python3; do if [ -x "$PY_BIN" ]; then break fi done if [ -x "$PY_BIN" ]; then # 检查是否有 Team ID(腾讯签名会导致 orjson 无法加载) TEAM_ID=$(codesign -dvv "$PY_BIN" 2>&1 | grep "TeamIdentifier" | awk '{print $2}') if [ -n "$TEAM_ID" ] && [ "$TEAM_ID" != "not set" ]; then warn "Python 带有 Team ID 签名: $TEAM_ID → 可能导致 orjson 加载失败" info "正在修复: codesign -f -s - ..." codesign -f -s - "$PY_BIN" 2>&1 && ok "Python 代码签名已修复" || warn "修复失败,需手动执行" else ok "Python 代码签名正常(adhoc)" fi # 验证 orjson OK=$("$PY_BIN" -c "import orjson; print(orjson.__version__)" 2>/dev/null) if [ -n "$OK" ]; then ok "orjson $OK ✅" else warn "orjson 不可用,尝试安装依赖..." "$PY_BIN" -m pip install -r "$SCRIPT_DIR/requirements.txt" 2>&1 | tail -2 fi # 验证 Camoufox C_OK=$("$PY_BIN" -c "from camoufox import Camoufox; print(1)" 2>/dev/null) if [ "$C_OK" = "1" ]; then ok "Camoufox ✅" else warn "Camoufox 不可用,安装中..." "$PY_BIN" -m pip install camoufox 2>&1 | tail -2 fi fi # ── 步骤7: 同步 ORACLE 和授权 ── echo "" info "步骤7/7: 同步配置..." # 确保 ORACLE.yaml 可读 if [ -f "$AGENT_SYNC/ORACLE.yaml" ]; then ok "ORACLE.yaml 已就绪" else warn "ORACLE.yaml 不存在(可能尚未创建)" fi # ── 安装防泄露 pre-commit hook ── echo "" info "安装防泄露 hook..." HOOK_SRC="$AGENT_SYNC/00_bootstrap/hooks/pre-commit" HOOK_DST="$AGENT_SYNC/.git/hooks/pre-commit" if [ -f "$HOOK_SRC" ]; then cp "$HOOK_SRC" "$HOOK_DST" && chmod +x "$HOOK_DST" ok "pre-commit hook 已安装(提交前自动拦截 API Key)" else warn "未找到 pre-commit hook 源文件,跳过" fi # 提醒用户 echo "" echo "============================================" ok "部署完成!" echo "" echo " ✅ 环境变量: AGENT_SYNC/AGENT_LOCAL 已写入 shell 配置文件" echo " ✅ 目录结构: $AGENT_LOCAL 已创建" echo " ✅ 本地配置: $AGENT_LOCAL/config.yaml" echo " ✅ ORACLE 宪法: $AGENT_SYNC/ORACLE.yaml" echo " ✅ 防泄露 hook: 已安装(API Key 提交将被拦截)" echo "" echo " 后续手动步骤:" echo " 1. 使环境变量生效: source ~/.zshrc" echo " 2. 配置你自己的 API 密钥(重要!):" echo " 打开 Dashboard → 服务 → 🔑 API 配置" echo " 或用环境变量: export DEEPSEEK_API_KEY=sk-xxx / DASHSCOPE_API_KEY=sk-xxx" echo " (密钥只存本机 agent-local,不会提交到仓库)" echo " 3. (如未安装 Tailscale)安装并登录:" echo " brew install --cask tailscale" echo " 或从 https://tailscale.com/download 下载" echo " 4. 开启远程登录(每台机器一次):" echo " sudo systemsetup -setremotelogin on" echo "============================================"