firewall.sh: - TCP Window Size 设为 65535(macOS 默认,Linux 服务器默认 29200) - 持久化到 /etc/sysctl.conf maintenance/update-cli-version.sh: - 从 npm registry 获取 @anthropic-ai/claude-code 最新版本 - 自动更新 proxy.js 中的 CLI_VERSION - 支持 --check(仅检查)/ --force VER(强制指定) - 建议 cron 每天 03:00 ET 运行
115 lines
3.9 KiB
Bash
Executable File
115 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
||
# update-cli-version.sh — 自动追踪并更新 Claude CLI 版本号
|
||
#
|
||
# 原理:
|
||
# 从 npm registry 拉取 @anthropic-ai/claude-code 最新版本,
|
||
# 更新 proxy.js 和 docker-compose 中的 CLI_VERSION 环境变量。
|
||
# 建议通过 cron 每天运行一次。
|
||
#
|
||
# 用法:
|
||
# bash update-cli-version.sh # 检查并更新
|
||
# bash update-cli-version.sh --check # 仅检查,不写入
|
||
# bash update-cli-version.sh --force VER # 强制设定版本
|
||
#
|
||
# cron 示例(每天 3 点,时区 America/New_York):
|
||
# 0 3 * * * /bin/bash /path/to/update-cli-version.sh >> /var/log/cli-version.log 2>&1
|
||
|
||
set -euo pipefail
|
||
|
||
PROXY_JS="$(dirname "$0")/../node-tls-proxy/proxy.js"
|
||
LOG_FILE="/tmp/cli-version-update.log"
|
||
DRY_RUN=false
|
||
FORCE_VERSION=""
|
||
|
||
# 解析参数
|
||
case "${1:-}" in
|
||
--check) DRY_RUN=true ;;
|
||
--force) FORCE_VERSION="${2:-}" ;;
|
||
esac
|
||
|
||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S') ET] $*" | tee -a "$LOG_FILE"; }
|
||
|
||
# ── 当前版本 ──────────────────────────────────────────────────
|
||
current_version() {
|
||
grep -oP "CLI_VERSION = process\.env\.CLI_VERSION \|\| '\K[0-9]+\.[0-9]+\.[0-9]+" "$PROXY_JS" 2>/dev/null || echo "unknown"
|
||
}
|
||
|
||
# ── 从 npm 拉取最新版本 ───────────────────────────────────────
|
||
fetch_latest_version() {
|
||
# 尝试 npm registry (JSON API)
|
||
local ver
|
||
ver=$(curl -sf --max-time 10 \
|
||
"https://registry.npmjs.org/@anthropic-ai/claude-code/latest" \
|
||
| grep -oP '"version"\s*:\s*"\K[0-9]+\.[0-9]+\.[0-9]+' \
|
||
| head -1) || true
|
||
|
||
if [ -z "$ver" ]; then
|
||
# 备用:npm view(需要 npm 可用)
|
||
ver=$(npm view @anthropic-ai/claude-code version 2>/dev/null) || true
|
||
fi
|
||
|
||
echo "${ver:-}"
|
||
}
|
||
|
||
# ── 版本比较:$1 > $2 时返回 0 ──────────────────────────────
|
||
version_gt() {
|
||
local a="$1" b="$2"
|
||
[ "$a" = "$b" ] && return 1
|
||
local sorted
|
||
sorted=$(printf '%s\n%s\n' "$a" "$b" | sort -V | head -1)
|
||
[ "$sorted" = "$b" ]
|
||
}
|
||
|
||
# ── 更新 proxy.js 中的版本号 ─────────────────────────────────
|
||
update_proxy_js() {
|
||
local new_ver="$1"
|
||
if [ ! -f "$PROXY_JS" ]; then
|
||
log "ERROR: proxy.js not found at $PROXY_JS"
|
||
return 1
|
||
fi
|
||
sed -i "s|CLI_VERSION = process\.env\.CLI_VERSION || '[0-9.]*'|CLI_VERSION = process.env.CLI_VERSION || '${new_ver}'|" "$PROXY_JS"
|
||
log " proxy.js: CLI_VERSION updated to $new_ver"
|
||
}
|
||
|
||
# ── 主流程 ────────────────────────────────────────────────────
|
||
main() {
|
||
local current latest
|
||
|
||
current=$(current_version)
|
||
log "Current CLI_VERSION: $current"
|
||
|
||
if [ -n "$FORCE_VERSION" ]; then
|
||
latest="$FORCE_VERSION"
|
||
log "Force mode: target version = $latest"
|
||
else
|
||
log "Fetching latest version from npm..."
|
||
latest=$(fetch_latest_version)
|
||
if [ -z "$latest" ]; then
|
||
log "ERROR: Failed to fetch version from npm. Keeping current."
|
||
exit 1
|
||
fi
|
||
log "Latest CLI_VERSION on npm: $latest"
|
||
fi
|
||
|
||
if [ "$current" = "$latest" ]; then
|
||
log "Already up to date ($current). No changes needed."
|
||
exit 0
|
||
fi
|
||
|
||
if ! version_gt "$latest" "$current" && [ -z "$FORCE_VERSION" ]; then
|
||
log "npm version ($latest) is not newer than current ($current). Skipping."
|
||
exit 0
|
||
fi
|
||
|
||
if $DRY_RUN; then
|
||
log "DRY RUN: would update $current -> $latest (use without --check to apply)"
|
||
exit 0
|
||
fi
|
||
|
||
log "Updating $current -> $latest ..."
|
||
update_proxy_js "$latest"
|
||
log "Done. Restart node-tls-proxy to apply: docker compose restart node-tls-proxy"
|
||
}
|
||
|
||
main
|