#!/bin/bash # Duckweed 一键安装脚本 # 用法: curl -fsSL https://www.duckweed.ai/install.sh | bash set -eu DUCKWEED_HOME="${DUCKWEED_HOME:-$HOME/.duckweed}" DUCKWEED_REPO="https://www.duckweed.ai/releases/duckweed-latest.tar.gz" VERSION="0.1.0" # ── 颜色输出 ── RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' info() { echo -e "${BLUE}[Duckweed]${NC} $*"; } ok() { echo -e "${GREEN}[Duckweed]${NC} $*"; } warn() { echo -e "${YELLOW}[Duckweed]${NC} $*"; } err() { echo -e "${RED}[Duckweed]${NC} $*" >&2; } # ── 步骤 1: 安装 uv ── install_uv() { if command -v uv &>/dev/null; then ok "uv 已安装: $(uv --version)" return 0 fi info "正在安装 uv (Python 包管理器)..." if command -v curl &>/dev/null; then curl -LsSf https://astral.sh/uv/install.sh | sh elif command -v wget &>/dev/null; then wget -qO- https://astral.sh/uv/install.sh | sh else err "需要 curl 或 wget,请先安装" exit 1 fi # 确保 uv 在 PATH 中 export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH" if command -v uv &>/dev/null; then ok "uv 安装成功: $(uv --version)" else err "uv 安装失败" exit 1 fi } # ── 步骤 2: 下载 Duckweed ── download_duckweed() { if [ -d "$DUCKWEED_HOME" ] && [ -f "$DUCKWEED_HOME/pyproject.toml" ]; then warn "已存在安装: $DUCKWEED_HOME" info "正在更新..." # 如果是 git 仓库,尝试 pull if [ -d "$DUCKWEED_HOME/.git" ]; then (cd "$DUCKWEED_HOME" && git pull --ff-only 2>/dev/null) || true return 0 fi fi info "正在下载 Duckweed v${VERSION}..." mkdir -p "$DUCKWEED_HOME" local tmpfile="/tmp/duckweed-dl-$$.tar.gz" rm -f "$tmpfile" if command -v curl &>/dev/null; then curl -fsSL "$DUCKWEED_REPO" -o "$tmpfile" else wget -q "$DUCKWEED_REPO" -O "$tmpfile" fi # 解压到 DUCKWEED_HOME tar xzf "$tmpfile" -C "$DUCKWEED_HOME" rm -f "$tmpfile" ok "下载完成: $DUCKWEED_HOME" } # ── 步骤 3: 安装 Python 依赖 ── install_deps() { info "正在安装 Python 依赖..." cd "$DUCKWEED_HOME" # 创建 venv(uv 自动下载 Python 3.10 如果不存在) info "创建虚拟环境..." uv venv --python 3.10 .venv 2>&1 | tail -3 # 安装核心依赖(不含 optional extras 避免解析问题) info "安装依赖包..." uv pip install --python .venv/bin/python -e . 2>&1 | tail -5 ok "Python 依赖安装完成" } # ── 步骤 4: 初始化数据目录 ── init_data() { info "正在初始化数据目录..." cd "$DUCKWEED_HOME" .venv/bin/python -m scripts.cli init 2>/dev/null || { # 手动创建基础目录 mkdir -p data/{identity,graph/nodes,raw_logs,projects,vault,kubeconfig} } ok "数据目录已初始化" } # ── 步骤 5: 创建全局命令 ── create_wrapper() { local bin_dir="$HOME/.local/bin" mkdir -p "$bin_dir" cat > "$bin_dir/duckweed" << 'WRAPPER' #!/usr/bin/env bash # Duckweed CLI wrapper — auto-generated by installer DUCKWEED_HOME="${DUCKWEED_HOME:-$HOME/.duckweed}" export DUCKWEED_HOME if [ ! -d "$DUCKWEED_HOME" ]; then echo "[Duckweed] 未找到安装目录: $DUCKWEED_HOME" echo "[Duckweed] 请重新运行安装脚本" exit 1 fi cd "$DUCKWEED_HOME" exec .venv/bin/python -m scripts.cli "$@" WRAPPER chmod +x "$bin_dir/duckweed" ok "命令已创建: $bin_dir/duckweed" # 检查 PATH if [[ ":$PATH:" != *":$bin_dir:"* ]]; then warn "$bin_dir 不在 PATH 中" warn "请将以下行添加到 ~/.bashrc 或 ~/.zshrc:" echo "" echo " export PATH=\"\$HOME/.local/bin:\$PATH\"" echo "" fi } # ── 步骤 6: 创建桌面快捷方式 (Linux) ── create_desktop_shortcut() { # 仅在有桌面环境时创建 local desktop_dir desktop_dir=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop") if [ ! -d "$desktop_dir" ]; then # 无桌面环境(服务器),跳过 return fi local apps_dir="$HOME/.local/share/applications" mkdir -p "$apps_dir" # 复制 logo(如果存在) local icon_path="$DUCKWEED_HOME/app/public/logo.png" if [ ! -f "$icon_path" ]; then icon_path="$DUCKWEED_HOME/logo.jpg" fi if [ ! -f "$icon_path" ]; then icon_path="" fi # 创建 .desktop 文件 cat > "$apps_dir/duckweed.desktop" << DESKTOP [Desktop Entry] Version=1.0 Type=Application Name=Duckweed Comment=认知记忆开发系统 Exec=$HOME/.local/bin/duckweed Icon=${icon_path} Terminal=true Categories=Development; StartupNotify=true DESKTOP chmod +x "$apps_dir/duckweed.desktop" # 复制到桌面 cp "$apps_dir/duckweed.desktop" "$desktop_dir/duckweed.desktop" 2>/dev/null || true chmod +x "$desktop_dir/duckweed.desktop" 2>/dev/null || true ok "桌面快捷方式已创建" } # ── 主流程 ── main() { echo "" echo -e "${BLUE}╔══════════════════════════════════════╗${NC}" echo -e "${BLUE}║ Duckweed 认知记忆开发系统 ║${NC}" echo -e "${BLUE}║ 一键安装 v${VERSION} ║${NC}" echo -e "${BLUE}╚══════════════════════════════════════╝${NC}" echo "" install_uv download_duckweed install_deps init_data create_wrapper create_desktop_shortcut echo "" echo -e "${GREEN}══════════════════════════════════════${NC}" echo -e "${GREEN} 安装完成!${NC}" echo -e "${GREEN}══════════════════════════════════════${NC}" echo "" echo " 常用命令:" echo " duckweed 启动服务 + 打开浏览器" echo " duckweed status 查看状态" echo " duckweed doctor 检查环境" echo " duckweed update 更新版本" echo " duckweed uninstall 卸载" echo "" echo " 安装目录: $DUCKWEED_HOME" echo "" # 自动启动服务 info "正在启动 Duckweed..." exec "$HOME/.local/bin/duckweed" } main "$@"