205 lines
5.2 KiB
Bash
Executable File
205 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
# ========================
|
|
# 常量定义
|
|
# ========================
|
|
SCRIPT_NAME=$(basename "$0")
|
|
NODE_MIN_VERSION=18
|
|
NODE_INSTALL_VERSION=22
|
|
NVM_VERSION="v0.40.3"
|
|
CLAUDE_PACKAGE="@anthropic-ai/claude-code"
|
|
CONFIG_DIR="$HOME/.claude"
|
|
CONFIG_FILE="$CONFIG_DIR/settings.json"
|
|
API_BASE_URL="https://api.z.ai/api/anthropic"
|
|
API_KEY_URL="https://z.ai/manage-apikey/apikey-list"
|
|
API_TIMEOUT_MS=3000000
|
|
|
|
# ========================
|
|
# 工具函数
|
|
# ========================
|
|
|
|
log_info() {
|
|
echo "🔹 $*"
|
|
}
|
|
|
|
log_success() {
|
|
echo "✅ $*"
|
|
}
|
|
|
|
log_error() {
|
|
echo "❌ $*" >&2
|
|
}
|
|
|
|
ensure_dir_exists() {
|
|
local dir="$1"
|
|
if [ ! -d "$dir" ]; then
|
|
mkdir -p "$dir" || {
|
|
log_error "Failed to create directory: $dir"
|
|
exit 1
|
|
}
|
|
fi
|
|
}
|
|
|
|
# ========================
|
|
# Node.js 安装函数
|
|
# ========================
|
|
|
|
install_nodejs() {
|
|
local platform=$(uname -s)
|
|
|
|
case "$platform" in
|
|
Linux|Darwin)
|
|
log_info "Installing Node.js on $platform..."
|
|
|
|
# 安装 nvm
|
|
log_info "Installing nvm ($NVM_VERSION)..."
|
|
curl -s https://raw.githubusercontent.com/nvm-sh/nvm/"$NVM_VERSION"/install.sh | bash
|
|
|
|
# 加载 nvm
|
|
log_info "Loading nvm environment..."
|
|
\. "$HOME/.nvm/nvm.sh"
|
|
|
|
# 安装 Node.js
|
|
log_info "Installing Node.js $NODE_INSTALL_VERSION..."
|
|
nvm install "$NODE_INSTALL_VERSION"
|
|
|
|
# 验证安装
|
|
node -v &>/dev/null || {
|
|
log_error "Node.js installation failed"
|
|
exit 1
|
|
}
|
|
log_success "Node.js installed: $(node -v)"
|
|
log_success "npm version: $(npm -v)"
|
|
;;
|
|
*)
|
|
log_error "Unsupported platform: $platform"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# ========================
|
|
# Node.js 检查函数
|
|
# ========================
|
|
|
|
check_nodejs() {
|
|
if command -v node &>/dev/null; then
|
|
current_version=$(node -v | sed 's/v//')
|
|
major_version=$(echo "$current_version" | cut -d. -f1)
|
|
|
|
if [ "$major_version" -ge "$NODE_MIN_VERSION" ]; then
|
|
log_success "Node.js is already installed: v$current_version"
|
|
return 0
|
|
else
|
|
log_info "Node.js v$current_version is installed but version < $NODE_MIN_VERSION. Upgrading..."
|
|
install_nodejs
|
|
fi
|
|
else
|
|
log_info "Node.js not found. Installing..."
|
|
install_nodejs
|
|
fi
|
|
}
|
|
|
|
# ========================
|
|
# Claude Code 安装
|
|
# ========================
|
|
|
|
install_claude_code() {
|
|
if command -v claude &>/dev/null; then
|
|
log_success "Claude Code is already installed: $(claude --version)"
|
|
else
|
|
log_info "Installing Claude Code..."
|
|
npm install -g "$CLAUDE_PACKAGE" || {
|
|
log_error "Failed to install claude-code"
|
|
exit 1
|
|
}
|
|
log_success "Claude Code installed successfully"
|
|
fi
|
|
}
|
|
|
|
configure_claude_json(){
|
|
node --eval '
|
|
const os = require("os");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const homeDir = os.homedir();
|
|
const filePath = path.join(homeDir, ".claude.json");
|
|
if (fs.existsSync(filePath)) {
|
|
const content = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
fs.writeFileSync(filePath, JSON.stringify({ ...content, hasCompletedOnboarding: true }, null, 2), "utf-8");
|
|
} else {
|
|
fs.writeFileSync(filePath, JSON.stringify({ hasCompletedOnboarding: true }, null, 2), "utf-8");
|
|
}'
|
|
}
|
|
|
|
# ========================
|
|
# API Key 配置
|
|
# ========================
|
|
|
|
configure_claude() {
|
|
log_info "Configuring Claude Code..."
|
|
echo " You can get your API key from: $API_KEY_URL"
|
|
read -s -p "🔑 Please enter your ZHIPU API key: " api_key
|
|
echo
|
|
|
|
if [ -z "$api_key" ]; then
|
|
log_error "API key cannot be empty. Please run the script again."
|
|
exit 1
|
|
fi
|
|
|
|
ensure_dir_exists "$CONFIG_DIR"
|
|
|
|
# 写入配置文件
|
|
node --eval '
|
|
const os = require("os");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const homeDir = os.homedir();
|
|
const filePath = path.join(homeDir, ".claude", "settings.json");
|
|
const apiKey = "'"$api_key"'";
|
|
|
|
const content = fs.existsSync(filePath)
|
|
? JSON.parse(fs.readFileSync(filePath, "utf-8"))
|
|
: {};
|
|
|
|
fs.writeFileSync(filePath, JSON.stringify({
|
|
...content,
|
|
env: {
|
|
ANTHROPIC_AUTH_TOKEN: apiKey,
|
|
ANTHROPIC_BASE_URL: "'"$API_BASE_URL"'",
|
|
API_TIMEOUT_MS: "'"$API_TIMEOUT_MS"'",
|
|
}
|
|
}, null, 2), "utf-8");
|
|
' || {
|
|
log_error "Failed to write settings.json"
|
|
exit 1
|
|
}
|
|
|
|
log_success "Claude Code configured successfully"
|
|
}
|
|
|
|
# ========================
|
|
# 主流程
|
|
# ========================
|
|
|
|
main() {
|
|
echo "🚀 Starting $SCRIPT_NAME"
|
|
|
|
check_nodejs
|
|
install_claude_code
|
|
configure_claude_json
|
|
configure_claude
|
|
|
|
echo ""
|
|
log_success "🎉 Installation completed successfully!"
|
|
echo ""
|
|
echo "🚀 You can now start using Claude Code with:"
|
|
echo " claude"
|
|
}
|
|
|
|
main "$@"
|