commit 2d68446059610d7c72347ec9d11fadc4ec3b7ee8 Author: YANG JIANKUAN Date: Mon Nov 3 23:32:29 2025 +0800 init: init proj diff --git a/cc-env-from-profiles.sh b/cc-env-from-profiles.sh new file mode 100755 index 0000000..ab7168a --- /dev/null +++ b/cc-env-from-profiles.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +# 轻量版 Claude Code 环境变量部署脚本(基于 profiles.json) +# 要求: +# 1) 读取 profiles.json 展示可选列表 +# 2) 选择后按照 env-deploy.sh 的参数写入:ANTHROPIC_BASE_URL、ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN(空) +# 3) 略去不必要的环境检查,假定环境完备(含 jq、node 可用) +# 4) 使用 Node 调用 /Users/kid/.claude/cc-aicodemirror-statusline-plus/save-cookie.js 传入所选 profile 的 cookie + +set -e + +BLUE='\033[0;34m' +GREEN='\033[0;32m' +RED='\033[1;31m' +NC='\033[0m' + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROFILES_JSON="$SCRIPT_DIR/profiles.json" +ANTHROPIC_BASE_URL="https://api.aicodemirror.com/api/claudecode" + +echo -e "\n${BLUE}========================================${NC}" +echo -e "${BLUE}Claude Code Profile 部署${NC}" +echo -e "${BLUE}========================================${NC}\n" + +# 读取 profiles.json 并展示列表 +if [ ! -f "$PROFILES_JSON" ]; then + echo -e "${RED}[ERROR]${NC} 未找到 profiles.json:$PROFILES_JSON" + exit 1 +fi + +COUNT=$(jq '.profiles | length' "$PROFILES_JSON") +if [ "$COUNT" -eq 0 ]; then + echo -e "${RED}[ERROR]${NC} profiles.json 中未找到任何 profiles" + exit 1 +fi + +echo -e "可用的 Profiles:" +for ((i=0; i/dev/null || true + sed -i.tmp -E '/^[[:space:]]*set[[:space:]]+-x[[:space:]]+ANTHROPIC_API_KEY/d' "$CONFIG_FILE" 2>/dev/null || true + sed -i.tmp -E '/^[[:space:]]*set[[:space:]]+-x[[:space:]]+ANTHROPIC_AUTH_TOKEN/d' "$CONFIG_FILE" 2>/dev/null || true + else + sed -i.tmp -E '/^[[:space:]]*export[[:space:]]+ANTHROPIC_BASE_URL=/d' "$CONFIG_FILE" 2>/dev/null || true + sed -i.tmp -E '/^[[:space:]]*export[[:space:]]+ANTHROPIC_API_KEY=/d' "$CONFIG_FILE" 2>/dev/null || true + sed -i.tmp -E '/^[[:space:]]*export[[:space:]]+ANTHROPIC_AUTH_TOKEN=/d' "$CONFIG_FILE" 2>/dev/null || true + fi + rm -f "$CONFIG_FILE.tmp" 2>/dev/null || true +fi + +# 追加新配置 +if [[ "$CURRENT_SHELL" == "fish" ]]; then + cat >> "$CONFIG_FILE" << EOF + +# Claude Code Environment Variables (auto from profiles) +set -x ANTHROPIC_BASE_URL "$ANTHROPIC_BASE_URL" +set -x ANTHROPIC_API_KEY "$API_KEY" +set -x ANTHROPIC_AUTH_TOKEN "" +# End Claude Code Environment Variables +EOF +else + cat >> "$CONFIG_FILE" << EOF + +# Claude Code Environment Variables (auto from profiles) +export ANTHROPIC_BASE_URL="$ANTHROPIC_BASE_URL" +export ANTHROPIC_API_KEY="$API_KEY" +export ANTHROPIC_AUTH_TOKEN="" +# End Claude Code Environment Variables +EOF +fi + +# 立刻在当前会话导出 +export ANTHROPIC_BASE_URL="$ANTHROPIC_BASE_URL" +export ANTHROPIC_API_KEY="$API_KEY" +export ANTHROPIC_AUTH_TOKEN="" + +echo -e "${GREEN}[OK]${NC} 已写入并激活环境变量:" +echo "ANTHROPIC_BASE_URL=$ANTHROPIC_BASE_URL" +echo "ANTHROPIC_API_KEY=****${API_KEY: -4}" +echo "ANTHROPIC_AUTH_TOKEN=\"\"" + +# 调用 Node 脚本保存 cookie +NODE_SCRIPT="/Users/kid/.claude/cc-aicodemirror-statusline-plus/save-cookie.js" +if [ -f "$NODE_SCRIPT" ]; then + node "$NODE_SCRIPT" "$COOKIE" + echo -e "${GREEN}[OK]${NC} 已调用 Node 保存 cookie" +else + echo -e "${RED}[WARN]${NC} 未找到 Node 脚本:$NODE_SCRIPT,跳过保存 cookie" +fi + +echo -e "\n${GREEN}完成!${NC} 新开终端会话即生效,或运行:source \"$CONFIG_FILE\"" + +exit 0 + + diff --git a/env-deploy.sh b/env-deploy.sh new file mode 100644 index 0000000..a8efd64 --- /dev/null +++ b/env-deploy.sh @@ -0,0 +1,327 @@ +#!/bin/bash + +# Claude Code Environment Setup Script +# Author: Claude Assistant +# Purpose: Automatically configure environment variables for Claude Code on macOS and Linux + +set -e # Exit on error + +# Colors for output +RED='\033[1;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored output +print_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +# Function to display current environment variables +display_current_env() { + print_info "当前环境变量状态:" + echo -e "${BLUE}----------------------------------------${NC}" + + # Get current shell type for proper variable display + CURRENT_SHELL=$(basename "$SHELL") + + if [[ "$CURRENT_SHELL" == "fish" ]]; then + # Fish shell syntax + echo "ANTHROPIC_BASE_URL=$(set -q ANTHROPIC_BASE_URL && echo $ANTHROPIC_BASE_URL || echo '(未设置)')" + echo "ANTHROPIC_API_KEY=$(set -q ANTHROPIC_API_KEY && echo '****'${ANTHROPIC_API_KEY: -4} || echo '(未设置)')" + echo "ANTHROPIC_AUTH_TOKEN=$(set -q ANTHROPIC_AUTH_TOKEN && echo $ANTHROPIC_AUTH_TOKEN || echo '(未设置)')" + else + # Bash/Zsh syntax + if [ -n "$ANTHROPIC_BASE_URL" ]; then + echo "ANTHROPIC_BASE_URL=$ANTHROPIC_BASE_URL" + else + echo "ANTHROPIC_BASE_URL=(未设置)" + fi + + if [ -n "$ANTHROPIC_API_KEY" ]; then + echo "ANTHROPIC_API_KEY=****${ANTHROPIC_API_KEY: -4}" + else + echo "ANTHROPIC_API_KEY=(未设置)" + fi + + if [ -n "$ANTHROPIC_AUTH_TOKEN" ]; then + echo "ANTHROPIC_AUTH_TOKEN=$ANTHROPIC_AUTH_TOKEN" + else + echo "ANTHROPIC_AUTH_TOKEN=(未设置)" + fi + fi + + echo -e "${BLUE}----------------------------------------${NC}" +} + +# Header +echo -e "\n${BLUE}========================================${NC}" +echo -e "${BLUE}Claude Code Environment Setup${NC}" +echo -e "${BLUE}========================================${NC}\n" + +# Display current environment variables before any changes +display_current_env +echo + +# Check if API key is provided as argument +if [ $# -eq 0 ]; then + print_error "请提供API密钥作为参数" + echo "使用方法: $0 " + exit 1 +fi + +ANTHROPIC_API_KEY="$1" +ANTHROPIC_BASE_URL="https://api.aicodemirror.com/api/claudecode" + +# Detect OS and shell +detect_os_and_shell() { + print_info "检测操作系统和Shell环境..." + + # Detect OS + if [[ "$OSTYPE" == "darwin"* ]]; then + OS="macOS" + elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + OS="Linux" + else + print_error "不支持的操作系统: $OSTYPE" + exit 1 + fi + + # Detect Shell + CURRENT_SHELL=$(basename "$SHELL") + + # Determine config file based on shell + case "$CURRENT_SHELL" in + bash) + if [[ "$OS" == "macOS" ]]; then + CONFIG_FILE="$HOME/.bash_profile" + else + CONFIG_FILE="$HOME/.bashrc" + fi + ;; + zsh) + CONFIG_FILE="$HOME/.zshrc" + ;; + fish) + CONFIG_FILE="$HOME/.config/fish/config.fish" + ;; + *) + print_error "不支持的Shell: $CURRENT_SHELL" + exit 1 + ;; + esac + + print_success "检测完成 - 系统: $OS, Shell: $CURRENT_SHELL" + print_info "配置文件: $CONFIG_FILE" +} + +# Function to add environment variables to config file +add_env_vars() { + print_info "开始配置环境变量..." + + # Create backup + if [ -f "$CONFIG_FILE" ]; then + cp "$CONFIG_FILE" "$CONFIG_FILE.backup.$(date +%Y%m%d_%H%M%S)" + print_info "已备份原配置文件" + fi + + # Check if variables already exist + if grep -q "ANTHROPIC_BASE_URL" "$CONFIG_FILE" 2>/dev/null || grep -q "ANTHROPIC_API_KEY" "$CONFIG_FILE" 2>/dev/null; then + print_warning "检测到已存在的Claude Code环境变量配置" + print_info "正在清理所有现有配置..." + + # Remove ALL existing ANTHROPIC environment variable configurations + # For bash/zsh: export VARIABLE=... + # For fish: set -x VARIABLE ... + if [[ "$CURRENT_SHELL" == "fish" ]]; then + # Fish shell: remove 'set -x VARIABLE ...' patterns + # Using -E for extended regex on macOS/BSD sed + sed -i.tmp -E '/^[[:space:]]*set[[:space:]]+-x[[:space:]]+ANTHROPIC_BASE_URL/d' "$CONFIG_FILE" 2>/dev/null || true + sed -i.tmp -E '/^[[:space:]]*set[[:space:]]+-x[[:space:]]+ANTHROPIC_API_KEY/d' "$CONFIG_FILE" 2>/dev/null || true + sed -i.tmp -E '/^[[:space:]]*set[[:space:]]+-x[[:space:]]+ANTHROPIC_AUTH_TOKEN/d' "$CONFIG_FILE" 2>/dev/null || true + else + # Bash/Zsh: remove 'export VARIABLE=...' patterns + # Using -E for extended regex on macOS/BSD sed + sed -i.tmp -E '/^[[:space:]]*export[[:space:]]+ANTHROPIC_BASE_URL=/d' "$CONFIG_FILE" 2>/dev/null || true + sed -i.tmp -E '/^[[:space:]]*export[[:space:]]+ANTHROPIC_API_KEY=/d' "$CONFIG_FILE" 2>/dev/null || true + sed -i.tmp -E '/^[[:space:]]*export[[:space:]]+ANTHROPIC_AUTH_TOKEN=/d' "$CONFIG_FILE" 2>/dev/null || true + fi + + # Also remove the marked sections for backward compatibility + sed -i.tmp '/# Claude Code Environment Variables/,/# End Claude Code Environment Variables/d' "$CONFIG_FILE" 2>/dev/null || true + + # Clean up temporary files + rm -f "$CONFIG_FILE.tmp" + + print_success "已彻底清理所有旧配置,准备写入新配置" + fi + + # Add environment variables based on shell type + if [[ "$CURRENT_SHELL" == "fish" ]]; then + cat >> "$CONFIG_FILE" << EOF + +# Claude Code Environment Variables +set -x ANTHROPIC_BASE_URL "$ANTHROPIC_BASE_URL" +set -x ANTHROPIC_API_KEY "$ANTHROPIC_API_KEY" +set -x ANTHROPIC_AUTH_TOKEN "" +# End Claude Code Environment Variables +EOF + else + cat >> "$CONFIG_FILE" << EOF + +# Claude Code Environment Variables +export ANTHROPIC_BASE_URL="$ANTHROPIC_BASE_URL" +export ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" +export ANTHROPIC_AUTH_TOKEN="" +# End Claude Code Environment Variables +EOF + fi + + print_success "环境变量已写入配置文件" +} + +# Function to update .claude.json +update_claude_json() { + print_info "更新 ~/.claude.json 配置..." + + # Check if jq is installed + if ! command -v jq &> /dev/null; then + print_error "需要安装 jq 工具" + if [[ "$OS" == "macOS" ]]; then + print_info "请运行: brew install jq" + else + print_info "请运行: sudo apt-get install jq (Ubuntu/Debian) 或 sudo yum install jq (CentOS/RHEL)" + fi + return 1 + fi + + # Execute the jq command + print_info "添加API密钥到Claude配置..." + + # Get the last 20 characters of the API key + KEY_SUFFIX="${ANTHROPIC_API_KEY: -20}" + + # Create .claude.json if it doesn't exist + if [ ! -f "$HOME/.claude.json" ]; then + echo '{}' > "$HOME/.claude.json" + print_info "创建新的 ~/.claude.json 文件" + fi + + # Update the JSON file + if (cat ~/.claude.json 2>/dev/null || echo 'null') | jq --arg key "$KEY_SUFFIX" '(. // {}) | .customApiKeyResponses.approved |= ([.[]?, $key] | unique)' > ~/.claude.json.tmp; then + mv ~/.claude.json.tmp ~/.claude.json + print_success "Claude配置已更新" + + # Display the updated customApiKeyResponses + print_info "更新后的 customApiKeyResponses 内容:" + echo -e "${BLUE}----------------------------------------${NC}" + jq '.customApiKeyResponses' ~/.claude.json 2>/dev/null || echo "{}" + echo -e "${BLUE}----------------------------------------${NC}" + else + print_error "更新Claude配置失败" + rm -f ~/.claude.json.tmp + return 1 + fi +} + +# Function to source the config file +activate_config() { + print_info "激活配置..." + + # Export variables for current session + export ANTHROPIC_BASE_URL="$ANTHROPIC_BASE_URL" + export ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" + export ANTHROPIC_AUTH_TOKEN="" + + print_success "环境变量已在当前会话中激活" + print_info "要在新的终端会话中使用,请运行以下命令:" + + if [[ "$CURRENT_SHELL" == "fish" ]]; then + echo -e "${GREEN}source $CONFIG_FILE${NC}" + else + echo -e "${GREEN}source $CONFIG_FILE${NC}" + fi + + print_info "或者重新打开终端窗口" +} + +# Function to verify configuration +verify_config() { + print_info "验证配置..." + + # Check if variables are set + if [ -n "$ANTHROPIC_BASE_URL" ] && [ -n "$ANTHROPIC_API_KEY" ]; then + print_success "环境变量验证成功" + echo "ANTHROPIC_BASE_URL: $ANTHROPIC_BASE_URL" + echo "ANTHROPIC_API_KEY: ****${ANTHROPIC_API_KEY: -4}" + echo "ANTHROPIC_AUTH_TOKEN: ${ANTHROPIC_AUTH_TOKEN:-\"\"}" + else + print_error "环境变量验证失败" + return 1 + fi + + # Check .claude.json + if [ -f "$HOME/.claude.json" ]; then + if jq -e '.customApiKeyResponses.approved' "$HOME/.claude.json" &>/dev/null; then + print_success "Claude配置文件验证成功" + else + print_warning "Claude配置文件存在但可能不完整" + fi + else + print_error "Claude配置文件不存在" + fi +} + +# Main execution +main() { + # Step 1: Detect OS and Shell + detect_os_and_shell + echo + + # Step 2: Add environment variables + add_env_vars + echo + + # Step 3: Update .claude.json + update_claude_json + echo + + # Step 4: Activate configuration + activate_config + echo + + # Step 5: Verify configuration + verify_config + echo + + print_success "Claude Code环境配置完成!" + echo -e "${BLUE}========================================${NC}" + + # Important reminder in red + echo + echo -e "${RED}╔══════════════════════════════════════════════════════════╗${NC}" + echo -e "${RED}║ ║${NC}" + echo -e "${RED}║ 请关闭终端后重新打开,开始 claude code 使用~ ║${NC}" + echo -e "${RED}║ ║${NC}" + echo -e "${RED}╚══════════════════════════════════════════════════════════╝${NC}" + echo +} + +# Run main function +main + +# Exit successfully +exit 0 \ No newline at end of file diff --git a/profiles.json b/profiles.json new file mode 100644 index 0000000..9123ed3 --- /dev/null +++ b/profiles.json @@ -0,0 +1,14 @@ +{ + "profiles": [ + { + "name": "13814521983", + "api_key": "sk-ant-api03-YoEoLVS4EJH9uOBQJgzeMYFZfaJodI4dvx4BNpYA2-bHBZFWLxx8mo0PiKQY0x_AmUAwMIac1vkg9a0ZaSVmyQ", + "cookie": "__Host-authjs.csrf-token=659f23721e08bc5bc28996d7959013a960245b2f28761ab85e106c8d0d50cdab%7C935622ff6929472e0129e80013646f30b5723d8a8446fbce0782eb4a8f774b98; __Secure-authjs.callback-url=https%3A%2F%2Fwww.aicodemirror.com%2Flogin; acw_tc=3ccdc15c17616486308608870e6655e067dc2abe091523ce18d8e9e0c8e78b; __Secure-authjs.session-token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoidHJpaENuTkRQc3JoMDh6ZURKQ1FjVzRRTFFtanhuaGhyZGFMRGIyT05EbDR6enlGTERJcGgyZVE3dGRvc295dzRIYzA2emI2QWVxVmVTYUpxX0ZmaFEifQ..spYdNTCrmHl8eveURhJbyA.QvoV-eTr3Wl7O9uMN1FrFxI-G5pSewonO6LnmiHY0hoZr4jjAD6mfN1zB-28ffsq0q_l7Le9w0X2P-PCTJ0u5BassjzyAGUyjBSYJdFsRlG71UCGcxevKfGXMoPstnljdPN2GnAO6PVNWv-X6BQgH3_m6_rKdVMVsnLF2RCJhPnlnAKqspMwio-B5t3KCpvuLAJH39s_NCDHpv2AdMLagroIgKpJT6wOCbrUeqJsLS-EBqs0q-5ddFZg0dAsXpgv22tNqdzVk_PipjBbQmDPkcYvfhoI68kI3LsHk-nJ9lIQIEfmAP-pqBCnvyYSvIQuLx2UvUndp60FCj-ehKwqnvX6nNtrK3ACoX6ElXkjC-bGcfJTxGsaMcgtBHeTjk9-bjQoXKo8Dundd4EL2DXd09KqbHvmWbk0bnzan9sulCRaSVZTYDSo-MNVeQEj7xM810zdU4EgKQe3OorQ0QdD4L1qdSw4_0m-FrOVsbpDp7rcvfMk71nkvdTB4DFG6jobGCti87w8JMSZkuJ4LWB0iw.VL51CZrb6qNNlMQG4F_aduqDPpeMyt9OR7jgFhM8CrI" + }, + { + "name": "17798517295", + "api_key": "sk-ant-api03-6ITk9R4kvZZtnYB_Dt584N5HGFd8wtg5DKjn099ycTyF6RQXajAXjICLptgykGVT0XpIFeJjwg9PZq4JolVs4A", + "cookie": "__Host-authjs.csrf-token=da5c90449ce978340397cb2eb872ae4d3c3887f07175e02a4e4c2c37c9c63620%7Cb935baa107158404f3aac17988113b2364e88a29b0909a57cb10dbb0fa980a6a; __Secure-authjs.callback-url=https%3A%2F%2Fwww.aicodemirror.com%2Flogin; acw_tc=b65cfd3317618260638344619e75228e781b089b1266501660d3933209dcf2; __Secure-authjs.session-token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoidHJpaENuTkRQc3JoMDh6ZURKQ1FjVzRRTFFtanhuaGhyZGFMRGIyT05EbDR6enlGTERJcGgyZVE3dGRvc295dzRIYzA2emI2QWVxVmVTYUpxX0ZmaFEifQ..n9LhECwXn66y4f4cGDqYew.p6EP9g5rNvkvnnIkAIPmdR_BU_-AUsTPbngXRO_Cs7Y8rZaaetIi1WGPG48_ke-KVtrGphMVc0HOqjjNcO6d9kPyPG7pIqTdCOgKqY98l1Jz0gNyGvvIw2xIBodHMZkTElHF-24hpCb2ra6KgLLvMTmZTW_myWGrIxiMF5wQS3ivm7W2KDhU0dTKck6XlzVUqy8DGuLXcLsZyakUJ8WPzlCOlVCiWsPHAXzyKAH7CmtDsTXNQTZbVAVURXHh_aFHnj0CuZ07ZQrOI5bml0KbXTg7C9bDczJyIe-CEIizs4jyeIk_tHwH190tjxnWYUxCNW4AyptHqJxobWkbY7iXoCr33Pa_hfsa--jVwBakjzGuC_QIt6bUzAuQ3UU8L3AScNPeZCAzwOwdkrhIDMx-l31N_QthV_76O9pyijOeS0aRpqlrbRgeYX7Hoag4U_BHIPx3yQKQOKjFi1UGUBmbEfXm4x-l_VEV4TBg1c0qwzXLH82MY275QrJY6xZvavrAibbSzWHifHP3PsD8jiFc5w.Nf7fookSbiXSt3hv1a8z5LwP_qC_fYmV3FLumtSRUrc" + } + ] +}