功能(tools): 添加多 Provider 启动脚本和动态上下文配置
- 新增 runcc.sh 支持 GLM/DeepSeek 等多 Provider 动态切换 - 新增 .env.example 模板和 .gitignore 保护敏感配置 - 新增 bashrc.tail.sh 提供模型快捷别名和 tmux pane 级模型隔离 - 重构 status_line.sh 支持动态上下文窗口显示和压缩状态提示 - 移除 settings.json 中硬编码的压缩参数,改由 runcc.sh 动态管理
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
{
|
{
|
||||||
"env": {
|
"env": {
|
||||||
"CLAUDE_CODE_AUTO_COMPACT_WINDOW": "200000",
|
|
||||||
"CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "75",
|
|
||||||
"CLAUDE_CODE_NO_FLICKER": "1"
|
"CLAUDE_CODE_NO_FLICKER": "1"
|
||||||
},
|
},
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# ── Provider 选择 ────────────────────────────────────────
|
||||||
|
# 变量命名规则: <PROVIDER>_BASE_URL, <PROVIDER>_AUTH_TOKEN, <PROVIDER>_DEFAULT_MODEL, <PROVIDER>_CONTEXT_WINDOW
|
||||||
|
# 例如 CC_PROVIDER=glm → 读取 GLM_BASE_URL, GLM_AUTH_TOKEN, GLM_DEFAULT_MODEL, GLM_CONTEXT_WINDOW
|
||||||
|
CC_PROVIDER=glm
|
||||||
|
|
||||||
|
# ── Claude Code 路径配置 ──────────────────────────────────
|
||||||
|
# settings.json 路径(用于清理残留的旧配置)
|
||||||
|
SETTINGS_FILE=$HOME/.claude/settings.json
|
||||||
|
|
||||||
|
# ── GLM Coding Plan (open.bigmodel.cn) ──────────────────
|
||||||
|
GLM_BASE_URL=https://open.bigmodel.cn/api/anthropic
|
||||||
|
GLM_AUTH_TOKEN={{your_glm_api_key}}
|
||||||
|
GLM_DEFAULT_MODEL=51
|
||||||
|
GLM_CONTEXT_WINDOW=200000
|
||||||
|
GLM_COMPACT_PCT=75
|
||||||
|
|
||||||
|
# ── DeepSeek (api.deepseek.com) ─────────────────────────
|
||||||
|
# 取消注释以下行以启用 DeepSeek:
|
||||||
|
# DEEPSEEK_BASE_URL=https://api.deepseek.com/anthropic
|
||||||
|
# DEEPSEEK_AUTH_TOKEN={{your_deepseek_api_key}}
|
||||||
|
# DEEPSEEK_DEFAULT_MODEL=ds
|
||||||
|
# DEEPSEEK_CONTEXT_WINDOW=1000000
|
||||||
|
# DEEPSEEK_COMPACT_PCT=50
|
||||||
|
# DEEPSEEK_DISABLE_COMPACT=1
|
||||||
|
# DEEPSEEK_MAX_CONTEXT_TOKENS=1000000
|
||||||
|
|
||||||
|
# ── 添加新 Provider ──────────────────────────────────────
|
||||||
|
# 按以下格式添加即可,无需修改 runcc.sh:
|
||||||
|
# MYPROVIDER_BASE_URL=https://api.example.com/anthropic
|
||||||
|
# MYPROVIDER_AUTH_TOKEN=your-token
|
||||||
|
# MYPROVIDER_DEFAULT_MODEL=model-name
|
||||||
|
# MYPROVIDER_CONTEXT_WINDOW=200000
|
||||||
|
# MYPROVIDER_COMPACT_PCT=75
|
||||||
|
# MYPROVIDER_DISABLE_COMPACT=1 # 可选:禁用自动压缩(API 报告值 < 实际值时使用)
|
||||||
|
# MYPROVIDER_MAX_CONTEXT_TOKENS=1000000 # 可选:覆盖 Claude Code 的上下文窗口假设
|
||||||
|
# 然后设置 CC_PROVIDER=myprovider 即可使用
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.env
|
||||||
Executable
+40
@@ -0,0 +1,40 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# DevContainer .bashrc 追加配置
|
||||||
|
# 由 Dockerfile 通过 sed 替换占位符后追加到 ~/.bashrc
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# 别名配置
|
||||||
|
alias ll='ls -alhF --color=auto'
|
||||||
|
alias date='date "+%F %T %p %A %B"'
|
||||||
|
export TIME_STYLE='+%Y-%m-%d %H:%M:%S'
|
||||||
|
|
||||||
|
export BIN_PATH="$HOME/.local/bin"
|
||||||
|
|
||||||
|
# Claude Code 启动函数(参数透传至 runcc.sh,支持 -n/--name 走 /rename 持久化)
|
||||||
|
cc() { $BIN_PATH/runcc.sh "$@"; }
|
||||||
|
|
||||||
|
# 模型快捷方式: cc51, cc51 -n 后端, cc -n 后端 51 ...
|
||||||
|
alias cc45='cc 45'
|
||||||
|
alias cc45a='cc 45a'
|
||||||
|
alias cc46='cc 46'
|
||||||
|
alias cc47='cc 47'
|
||||||
|
alias cc5='cc 5'
|
||||||
|
alias cc5t='cc 5t'
|
||||||
|
alias cc51='cc 51'
|
||||||
|
|
||||||
|
# DeepSeek 快捷方式
|
||||||
|
alias ccds='cc -p deepseek ds'
|
||||||
|
alias ccdsf='cc -p deepseek dsf'
|
||||||
|
|
||||||
|
# tmux pane 级模型继承:从 pane option 读取模型配置(由 runcc.sh 写入)
|
||||||
|
# 覆盖 session 级环境变量,实现同 session 不同 pane 的模型隔离
|
||||||
|
if [ -n "${TMUX:-}" ]; then
|
||||||
|
_model="$(tmux show-option -pv @anthropic_model 2>/dev/null || true)"
|
||||||
|
if [ -n "$_model" ]; then
|
||||||
|
export ANTHROPIC_DEFAULT_HAIKU_MODEL="$_model"
|
||||||
|
export ANTHROPIC_DEFAULT_SONNET_MODEL="$_model"
|
||||||
|
export ANTHROPIC_DEFAULT_OPUS_MODEL="$_model"
|
||||||
|
fi
|
||||||
|
unset _model
|
||||||
|
|
||||||
|
fi
|
||||||
Executable
+177
@@ -0,0 +1,177 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Claude Code 启动脚本
|
||||||
|
# 支持多 Provider (通过 .env 配置,自动解析 ${PROVIDER}_BASE_URL / ${PROVIDER}_AUTH_TOKEN)
|
||||||
|
#
|
||||||
|
# 固定版本: 2.1.112 (来自 /workspace/.devcontainer/.cache/npm/anthropic-ai-claude-code-2.1.112.tgz)
|
||||||
|
# 注意: 不再执行自动更新,以保持版本稳定
|
||||||
|
|
||||||
|
# ── 路径配置 ──────────────────────────────────────────────
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ENV_FILE="${SCRIPT_DIR}/.env"
|
||||||
|
|
||||||
|
# ── 加载 .env 文件 ──────────────────────────────────────
|
||||||
|
if [ -f "$ENV_FILE" ]; then
|
||||||
|
while IFS= read -r line || [ -n "$line" ]; do
|
||||||
|
# 跳过注释和空行
|
||||||
|
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
||||||
|
[[ -z "${line// /}" ]] && continue
|
||||||
|
# 解析 key=value
|
||||||
|
key="${line%%=*}"
|
||||||
|
value="${line#*=}"
|
||||||
|
# 去除引号
|
||||||
|
[[ "$value" =~ ^\"(.*)\"$ ]] && value="${BASH_REMATCH[1]}"
|
||||||
|
[[ "$value" =~ ^\'(.*)\'$ ]] && value="${BASH_REMATCH[1]}"
|
||||||
|
# 仅导出合法变量名
|
||||||
|
if [[ "$key" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
|
||||||
|
export "$key=$value"
|
||||||
|
fi
|
||||||
|
done < "$ENV_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 参数解析 ──────────────────────────────────────────────
|
||||||
|
SESSION_NAME=""
|
||||||
|
MODEL_KEY=""
|
||||||
|
PROVIDER_OVERRIDE=""
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--name|-n)
|
||||||
|
[ $# -ge 2 ] || { echo "错误: --name 需要参数" >&2; exit 1; }
|
||||||
|
SESSION_NAME="$2"; shift 2
|
||||||
|
;;
|
||||||
|
--provider|-p)
|
||||||
|
[ $# -ge 2 ] || { echo "错误: --provider 需要参数" >&2; exit 1; }
|
||||||
|
PROVIDER_OVERRIDE="$2"; shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
echo "用法: runcc.sh [选项] [模型]"
|
||||||
|
echo ""
|
||||||
|
echo "选项:"
|
||||||
|
echo " --name, -n <名称> Claude Code 会话显示名称"
|
||||||
|
echo " --provider, -p <名称> API 提供商 (由 .env 配置,如 glm / deepseek)"
|
||||||
|
echo ""
|
||||||
|
echo "GLM 模型: 45|45a|46|47|5|5t|51"
|
||||||
|
echo "DeepSeek 模型: ds|dsf"
|
||||||
|
echo "其他: 直接传入模型名称"
|
||||||
|
echo ""
|
||||||
|
echo "Provider 变量规则: CC_PROVIDER=<name> → <NAME>_BASE_URL + <NAME>_AUTH_TOKEN"
|
||||||
|
echo " 添加新 Provider 只需在 .env 中按此格式添加变量即可"
|
||||||
|
echo ""
|
||||||
|
echo "示例:"
|
||||||
|
echo " runcc.sh # 默认 Provider + 默认模型"
|
||||||
|
echo " runcc.sh 47 # 默认 Provider + glm-4.7"
|
||||||
|
echo " runcc.sh --provider deepseek # DeepSeek + 默认模型"
|
||||||
|
echo " runcc.sh -p deepseek dsf # DeepSeek + deepseek-v4-flash"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
MODEL_KEY="$1"; shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── Provider 动态解析 ─────────────────────────────────────
|
||||||
|
# CC_PROVIDER=glm → GLM_BASE_URL, GLM_AUTH_TOKEN, GLM_DEFAULT_MODEL
|
||||||
|
# CC_PROVIDER=deepseek → DEEPSEEK_BASE_URL, DEEPSEEK_AUTH_TOKEN, DEEPSEEK_DEFAULT_MODEL
|
||||||
|
# CC_PROVIDER=xxx → XXX_BASE_URL, XXX_AUTH_TOKEN, XXX_DEFAULT_MODEL, XXX_CONTEXT_WINDOW
|
||||||
|
CC_PROVIDER="${PROVIDER_OVERRIDE:-${CC_PROVIDER:-glm}}"
|
||||||
|
upper_provider="$(echo "$CC_PROVIDER" | tr '[:lower:]' '[:upper:]')"
|
||||||
|
|
||||||
|
base_url_var="${upper_provider}_BASE_URL"
|
||||||
|
token_var="${upper_provider}_AUTH_TOKEN"
|
||||||
|
default_model_var="${upper_provider}_DEFAULT_MODEL"
|
||||||
|
context_window_var="${upper_provider}_CONTEXT_WINDOW"
|
||||||
|
compact_pct_var="${upper_provider}_COMPACT_PCT"
|
||||||
|
disable_compact_var="${upper_provider}_DISABLE_COMPACT"
|
||||||
|
max_ctx_var="${upper_provider}_MAX_CONTEXT_TOKENS"
|
||||||
|
|
||||||
|
ANTHROPIC_BASE_URL="${!base_url_var}"
|
||||||
|
ANTHROPIC_AUTH_TOKEN="${!token_var}"
|
||||||
|
DEFAULT_MODEL="${!default_model_var:-}"
|
||||||
|
CONTEXT_WINDOW="${!context_window_var:-200000}"
|
||||||
|
COMPACT_PCT="${!compact_pct_var:-75}"
|
||||||
|
DISABLE_COMPACT="${!disable_compact_var:-}"
|
||||||
|
MAX_CONTEXT_TOKENS="${!max_ctx_var:-}"
|
||||||
|
|
||||||
|
if [ -z "$ANTHROPIC_BASE_URL" ] || [ -z "$ANTHROPIC_AUTH_TOKEN" ]; then
|
||||||
|
echo "错误: Provider '$CC_PROVIDER' 未配置 BASE_URL 或 AUTH_TOKEN" >&2
|
||||||
|
echo "请在 ${ENV_FILE} 中添加: ${upper_provider}_BASE_URL, ${upper_provider}_AUTH_TOKEN" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export ANTHROPIC_BASE_URL ANTHROPIC_AUTH_TOKEN
|
||||||
|
export CC_CONTEXT_WINDOW="$CONTEXT_WINDOW"
|
||||||
|
|
||||||
|
# DISABLE_COMPACT 模式: 禁用自动压缩,覆盖上下文窗口(适用于 API 报告值 < 实际值的模型)
|
||||||
|
if [ "$DISABLE_COMPACT" = "1" ]; then
|
||||||
|
export DISABLE_COMPACT=1
|
||||||
|
export CLAUDE_CODE_MAX_CONTEXT_TOKENS="${MAX_CONTEXT_TOKENS:-$CONTEXT_WINDOW}"
|
||||||
|
else
|
||||||
|
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE="$COMPACT_PCT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 更新 settings.json ──────────────────────────────────
|
||||||
|
# 删除凭据、模型和窗口变量(由环境变量接管)
|
||||||
|
# SETTINGS_FILE 路径由 .env 配置,默认 ~/.claude/settings.json
|
||||||
|
SETTINGS_FILE="${SETTINGS_FILE:-$HOME/.claude/settings.json}"
|
||||||
|
if command -v jq &>/dev/null && [ -f "$SETTINGS_FILE" ]; then
|
||||||
|
jq 'del(.env.ANTHROPIC_BASE_URL, .env.ANTHROPIC_AUTH_TOKEN, .env.CLAUDE_CODE_AUTO_COMPACT_WINDOW, .env.CLAUDE_AUTOCOMPACT_PCT_OVERRIDE, .env.DISABLE_COMPACT, .env.CLAUDE_CODE_MAX_CONTEXT_TOKENS, .env.ANTHROPIC_DEFAULT_OPUS_MODEL, .env.ANTHROPIC_DEFAULT_HAIKU_MODEL, .env.ANTHROPIC_DEFAULT_SONNET_MODEL)' \
|
||||||
|
"$SETTINGS_FILE" > "${SETTINGS_FILE}.tmp" \
|
||||||
|
&& mv "${SETTINGS_FILE}.tmp" "$SETTINGS_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 模型解析 ──────────────────────────────────────────────
|
||||||
|
MODEL_KEY="${MODEL_KEY:-$DEFAULT_MODEL}"
|
||||||
|
|
||||||
|
case "$MODEL_KEY" in
|
||||||
|
# GLM 系列
|
||||||
|
45) MODEL="glm-4.5" ;;
|
||||||
|
45a) MODEL="glm-4.5-air" ;;
|
||||||
|
46) MODEL="glm-4.6" ;;
|
||||||
|
47) MODEL="glm-4.7" ;;
|
||||||
|
5) MODEL="glm-5" ;;
|
||||||
|
5t) MODEL="glm-5-turbo" ;;
|
||||||
|
51) MODEL="glm-5.1" ;;
|
||||||
|
# DeepSeek 系列
|
||||||
|
ds) MODEL="deepseek-v4-pro" ;;
|
||||||
|
dsf) MODEL="deepseek-v4-flash" ;;
|
||||||
|
# 其他: 直接作为模型名称
|
||||||
|
*) MODEL="$MODEL_KEY" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# ── 模型环境变量(三个层级统一为同一模型)────────────────
|
||||||
|
export ANTHROPIC_DEFAULT_HAIKU_MODEL="$MODEL"
|
||||||
|
export ANTHROPIC_DEFAULT_SONNET_MODEL="$MODEL"
|
||||||
|
export ANTHROPIC_DEFAULT_OPUS_MODEL="$MODEL"
|
||||||
|
|
||||||
|
# ── tmux 模型传播(确保子 pane 能获取正确模型)─────────
|
||||||
|
if [ -n "${TMUX:-}" ]; then
|
||||||
|
SESSION_ID="$(tmux display-message -p '#{session_id}')"
|
||||||
|
|
||||||
|
tmux setenv -t "$SESSION_ID" ANTHROPIC_DEFAULT_OPUS_MODEL "$MODEL"
|
||||||
|
tmux setenv -t "$SESSION_ID" ANTHROPIC_DEFAULT_HAIKU_MODEL "$MODEL"
|
||||||
|
tmux setenv -t "$SESSION_ID" ANTHROPIC_DEFAULT_SONNET_MODEL "$MODEL"
|
||||||
|
tmux setenv -t "$SESSION_ID" CC_CONTEXT_WINDOW "$CONTEXT_WINDOW"
|
||||||
|
|
||||||
|
if [ "$DISABLE_COMPACT" = "1" ]; then
|
||||||
|
tmux setenv -t "$SESSION_ID" DISABLE_COMPACT 1
|
||||||
|
tmux setenv -t "$SESSION_ID" CLAUDE_CODE_MAX_CONTEXT_TOKENS "${MAX_CONTEXT_TOKENS:-$CONTEXT_WINDOW}"
|
||||||
|
tmux setenv -u -t "$SESSION_ID" CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 2>/dev/null || true
|
||||||
|
else
|
||||||
|
tmux setenv -t "$SESSION_ID" CLAUDE_AUTOCOMPACT_PCT_OVERRIDE "$COMPACT_PCT"
|
||||||
|
tmux setenv -u -t "$SESSION_ID" DISABLE_COMPACT 2>/dev/null || true
|
||||||
|
tmux setenv -u -t "$SESSION_ID" CLAUDE_CODE_MAX_CONTEXT_TOKENS 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmux set-option -p @anthropic_model "$MODEL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 启动 Claude Code ────────────────────────────────────
|
||||||
|
CC_ARGS=(--ide --dangerously-skip-permissions --allow-dangerously-skip-permissions --effort max)
|
||||||
|
|
||||||
|
if [ -n "$SESSION_NAME" ]; then
|
||||||
|
INITIAL_PROMPT="/rename $SESSION_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "启动 Claude Code (provider: $CC_PROVIDER, 模型: $MODEL${SESSION_NAME:+, 会话: $SESSION_NAME})"
|
||||||
|
claude "${CC_ARGS[@]}" ${INITIAL_PROMPT:+"$INITIAL_PROMPT"}
|
||||||
@@ -3,15 +3,28 @@
|
|||||||
input=$(cat)
|
input=$(cat)
|
||||||
|
|
||||||
# Extract fields using jq
|
# Extract fields using jq
|
||||||
MODEL=$(echo "$input" | jq -r '.model.display_name' | sed 's/\[1m\]/[200k]/')
|
MODEL=$(echo "$input" | jq -r '.model.display_name')
|
||||||
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
|
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
|
||||||
V=$(echo "$input" | jq -r '.version')
|
V=$(echo "$input" | jq -r '.version')
|
||||||
|
|
||||||
|
# 上下文窗口大小(由 runcc.sh 根据 Provider 设置并写入 settings.json,
|
||||||
|
# 默认 200000。GLM=200k, DeepSeek=1M)
|
||||||
|
CC_CONTEXT_WINDOW="${CC_CONTEXT_WINDOW:-200000}"
|
||||||
|
|
||||||
|
# 格式化上下文窗口: 200000→200k, 1000000→1M
|
||||||
|
if [ "$CC_CONTEXT_WINDOW" -ge 1000000 ]; then
|
||||||
|
CW_DISPLAY="$((CC_CONTEXT_WINDOW / 1000000))M"
|
||||||
|
else
|
||||||
|
CW_DISPLAY="$((CC_CONTEXT_WINDOW / 1000))k"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 模型名后追加上下文窗口大小(避免重复追加)
|
||||||
|
if [[ "$MODEL" != *"$CW_DISPLAY"* ]]; then
|
||||||
|
MODEL="${MODEL} [${CW_DISPLAY}]"
|
||||||
|
fi
|
||||||
|
|
||||||
# 计算上下文使用占比
|
# 计算上下文使用占比
|
||||||
# JSON 中 used_percentage 是相对模型实际窗口(如 GLM 的 1M)计算的,
|
AUTO_COMPACT_WINDOW="$CC_CONTEXT_WINDOW"
|
||||||
# 但 /context 命令显示的是相对 auto-compact 窗口(200k)的占比。
|
|
||||||
# 因此需要用实际 token 数 / 200000 来获得正确的百分比。
|
|
||||||
AUTO_COMPACT_WINDOW=200000
|
|
||||||
PCT=$(echo "$input" | jq -r --argjson w "$AUTO_COMPACT_WINDOW" '
|
PCT=$(echo "$input" | jq -r --argjson w "$AUTO_COMPACT_WINDOW" '
|
||||||
((
|
((
|
||||||
(.context_window.current_usage.input_tokens // 0) +
|
(.context_window.current_usage.input_tokens // 0) +
|
||||||
@@ -34,4 +47,10 @@ elif git rev-parse --git-dir >/dev/null 2>&1; then
|
|||||||
REMOTE="🌐 $(git remote get-url origin 2>/dev/null)"
|
REMOTE="🌐 $(git remote get-url origin 2>/dev/null)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "版本:v$V | 模型:$MODEL | 上下文:${PCT}%"
|
# DISABLE_COMPACT 提醒:无自动压缩,需手动 /compact 或 /clear
|
||||||
|
COMPACT_HINT=""
|
||||||
|
if [ "${DISABLE_COMPACT:-0}" = "1" ]; then
|
||||||
|
COMPACT_HINT=" | ⚠无自动压缩"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "版本:v$V | 模型:$MODEL | 上下文:${PCT}%${COMPACT_HINT}"
|
||||||
|
|||||||
Reference in New Issue
Block a user