Files
tech/.claude/tools/runcc.sh
T
arno 911503d997 功能(ClaudeCode): 新增飞书联动工具链与会话管理增强
- 新增命令: lark-delegate(跨项目委派)、lark-inbox(收件箱)、lark-me(自发送)、stop(任务收尾)
- 新增工具: lark-consumer/consumer-ensure/inbox-check(飞书事件实时消费与会话隔离)、tmux-monitor(监控面板)
- runcc.sh 增加 --list/--kill/--send 操作模式与多会话自增命名
- CLAUDE.md 增加强制要求(汇报格式、收尾通知、上下文压缩)
2026-07-03 14:49:44 +08:00

448 lines
20 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Claude Code 启动脚本
# 支持多 Provider (通过 .env 配置,自动解析 ${PROVIDER}_BASE_URL / ${PROVIDER}_AUTH_TOKEN)
#
# 每天首次启动时自动执行 claude upgrade
# 始终通过 tmux 启动 claude,每次启动创建独立 session(以当前目录名命名)
# 同目录可多开,session 名末尾自增数字(dit-1 → dit-2 → dit-3
# pane 标题与 CC --name 使用 session_model 组合(如 dit-1_glm-5.2),window 名使用模型名
#
# tmux 配置参考: https://gitea.szis.com.cn/isos/team/src/branch/trunk/team/tmux.md
# ── 路径配置 ──────────────────────────────────────────────
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]}"
# 展开 value 中的环境变量引用(如 $HOME → /home/arno
eval "value=\"$value\""
# 仅导出合法变量名
if [[ "$key" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
export "$key=$value"
fi
done < "$ENV_FILE"
fi
# ── 参数解析 ──────────────────────────────────────────────
SESSION_NAME=""
MODEL_KEY=""
PROVIDER_OVERRIDE=""
ACTION="launch" # launch | list | kill | send
KILL_TARGET=""
SEND_TARGET=""
SEND_MESSAGE=""
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
;;
--list|-l)
ACTION="list"; shift
;;
--kill|-k)
[ $# -ge 2 ] || { echo "错误: --kill 需要 session 名称参数" >&2; exit 1; }
ACTION="kill"; KILL_TARGET="$2"; shift 2
;;
--send|-s)
[ $# -ge 3 ] || { echo "错误: --send 需要 <session> <消息>" >&2; exit 1; }
ACTION="send"; SEND_TARGET="$2"; SEND_MESSAGE="$3"; shift 3
;;
-h|--help)
echo "用法: runcc.sh [选项] [模型]"
echo ""
echo "操作模式:"
echo " (默认) 启动 Claude Code 会话"
echo " --list, -l 列出所有 CC tmux 会话(含 provider/模型信息)"
echo " --kill, -k <名称> 终止指定 CC 会话"
echo " --send, -s <会话> <消息> 向已有 CC 会话发送提示词"
echo ""
echo "启动选项:"
echo " --name, -n <名称> 会话显示名称"
echo " --provider, -p <名称> API 提供商 (由 .env 配置,如 glm / deepseek)"
echo ""
echo "GLM 模型: 45|45a|46|47|5|5t|51|52"
echo "Qwen 模型: qw37|qw36f"
echo "DeepSeek 模型: ds|dsf"
echo "其他: 直接传入模型名称"
echo ""
echo "Provider 变量规则: CC_PROVIDER=<name> → <NAME>_BASE_URL + <NAME>_AUTH_TOKEN"
echo " 添加新 Provider 只需在 .env 中按此格式添加变量即可"
echo ""
echo "快捷方式 (通过 ~/.bashrc 别名):"
echo " cc [模型] 默认 glm provider"
echo " ccds [模型] 默认 deepseek provider"
echo ""
echo "示例:"
echo " runcc.sh # 默认 Provider + 默认模型"
echo " runcc.sh 47 # 默认 Provider + glm-4.7"
echo " runcc.sh --provider qwen # Qwen + 默认模型"
echo " runcc.sh -p qwen qw37 # Qwen + qwen3.7-max"
echo " runcc.sh -l # 列出所有 CC 会话"
echo " runcc.sh -k glm-52 # 终止 glm-52 会话"
echo " runcc.sh -s glm-52 '你好' # 向 glm-52 发送消息"
exit 0
;;
*)
MODEL_KEY="$1"; shift
;;
esac
done
# ── 操作: --list ──────────────────────────────────────────
if [ "$ACTION" = "list" ]; then
echo "CC tmux 会话列表:"
echo "──────────────────────────────────────────────────────"
CC_COUNT=0
for s in $(tmux list-sessions -F '#{session_name}' 2>/dev/null); do
if tmux show-options -t "$s" @cc_provider 2>/dev/null | grep -q .; then
CC_COUNT=$((CC_COUNT + 1))
created=$(tmux display -t "$s" -p '#{session_created}' 2>/dev/null)
attached=$(tmux display -t "$s" -p '#{?session_attached,●,○}' 2>/dev/null)
provider=$(tmux show-options -t "$s" -v @cc_provider 2>/dev/null)
model=$(tmux show-options -t "$s" -v @cc_model 2>/dev/null)
printf " %s %s %s @cc_provider=%s @cc_model=%s\n" "$attached" "$s" "$created" "$provider" "$model"
fi
done
if [ "$CC_COUNT" -eq 0 ]; then
echo " (无 CC 会话)"
fi
echo "──────────────────────────────────────────────────────"
echo "●=已附加 ○=后台运行"
exit 0
fi
# ── 操作: --kill ──────────────────────────────────────────
if [ "$ACTION" = "kill" ]; then
if ! tmux has-session -t "$KILL_TARGET" 2>/dev/null; then
echo "错误: 会话 '$KILL_TARGET' 不存在" >&2
echo "可用 CC 会话:"
CC_LISTED=0
for s in $(tmux list-sessions -F '#{session_name}' 2>/dev/null); do
if tmux show-options -t "$s" @cc_provider 2>/dev/null | grep -q .; then
echo " $s"
CC_LISTED=1
fi
done
[ "$CC_LISTED" -eq 0 ] && echo " (无)"
exit 1
fi
tmux kill-session -t "$KILL_TARGET"
echo "已终止会话: $KILL_TARGET"
exit 0
fi
# ── 操作: --send ──────────────────────────────────────────
if [ "$ACTION" = "send" ]; then
if ! tmux has-session -t "$SEND_TARGET" 2>/dev/null; then
echo "错误: 会话 '$SEND_TARGET' 不存在" >&2
exit 1
fi
# 找第一个 pane(通常是 claude 主进程)
PANE_ID="$(tmux list-panes -t "$SEND_TARGET" -F '#{pane_id}' | head -1)"
tmux send-keys -t "$PANE_ID" -l "$SEND_MESSAGE"
tmux send-keys -t "$PANE_ID" Enter
echo "已向 $SEND_TARGET ($PANE_ID) 发送消息"
exit 0
fi
# ── Provider 动态解析 ─────────────────────────────────────
# 优先级:命令行 --provider > .env CC_PROVIDER > 默认 glm
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 ──────────────────────────────────
# 1) 删除凭据、模型和窗口变量(由环境变量接管)
# 2) 注入 statusLine / UserPromptSubmit hook(不存在则写入绝对路径)
# SETTINGS_FILE / STATUS_LINE_SCRIPT / USER_PROMPT_SUBMIT_SCRIPT 路径由 .env 配置
SETTINGS_FILE="${SETTINGS_FILE:-$HOME/.claude/settings.json}"
# 项目根目录:优先用 .env 的 SKILLS_DIR(语义清晰、跨机器可迁移);未配置则从脚本位置反推兜底
PROJECT_DIR="${SKILLS_DIR:-$(dirname "$(dirname "$SCRIPT_DIR")")}"
STATUS_LINE_SCRIPT="${STATUS_LINE_SCRIPT:-.claude/tools/status_line.sh}"
USER_PROMPT_SUBMIT_SCRIPT="${USER_PROMPT_SUBMIT_SCRIPT:-.claude/tools/user-prompt-submit.sh}"
# 相对路径 → 基于项目根目录的绝对路径
if [[ "$STATUS_LINE_SCRIPT" != /* ]]; then
STATUS_LINE_SCRIPT="${PROJECT_DIR}/${STATUS_LINE_SCRIPT#./}"
fi
if [[ "$USER_PROMPT_SUBMIT_SCRIPT" != /* ]]; then
USER_PROMPT_SUBMIT_SCRIPT="${PROJECT_DIR}/${USER_PROMPT_SUBMIT_SCRIPT#./}"
fi
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"
# 确保 statusLine 已配置且脚本可执行(键不存在或路径失效则写入/纠正)
SL_CUR="$(jq -r '.statusLine.command // empty' "$SETTINGS_FILE" 2>/dev/null)"
if [ -z "$SL_CUR" ] || [ ! -x "${SL_CUR%% *}" ]; then
jq --arg cmd "$STATUS_LINE_SCRIPT" \
'. + {"statusLine": {"type": "command", "command": $cmd}}' \
"$SETTINGS_FILE" > "${SETTINGS_FILE}.tmp" \
&& mv "${SETTINGS_FILE}.tmp" "$SETTINGS_FILE"
fi
# 确保 UserPromptSubmit hook 已配置且脚本可执行(键不存在或路径失效则写入/纠正)
UPS_CUR="$(jq -r '.hooks.UserPromptSubmit[0].hooks[0].command // empty' "$SETTINGS_FILE" 2>/dev/null)"
if [ -z "$UPS_CUR" ] || [ ! -x "${UPS_CUR%% *}" ]; then
jq --arg cmd "$USER_PROMPT_SUBMIT_SCRIPT" \
'.hooks += {"UserPromptSubmit": [{"hooks": [{"type": "command", "command": $cmd}]}]}' \
"$SETTINGS_FILE" > "${SETTINGS_FILE}.tmp" \
&& mv "${SETTINGS_FILE}.tmp" "$SETTINGS_FILE"
fi
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" ;;
52) MODEL="glm-5.2" ;;
# Qwen 系列
qw37) MODEL="qwen3.7-max" ;;
qw36f) MODEL="qwen3.6-flash" ;;
qwim) MODEL="qwen-image-max" ;;
# DeepSeek 系列
ds) MODEL="deepseek-v4-pro[1m]" ;;
dsf) MODEL="deepseek-v4-flash" ;;
# 其他: 直接作为模型名称
*) MODEL="$MODEL_KEY" ;;
esac
# ── 模型环境变量(三个层级统一为同一模型)────────────────
export ANTHROPIC_MODEL="$MODEL"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="$MODEL"
export ANTHROPIC_DEFAULT_SONNET_MODEL="$MODEL"
export ANTHROPIC_DEFAULT_OPUS_MODEL="$MODEL"
export CLAUDE_CODE_SUBAGENT_MODEL="$MODEL"
export CLAUDE_CODE_NO_FLICKER=1
# ── 会话命名规则:目录名-序号(如 dit-1、szis-2)───────────
DIR_NAME=$(basename "$PWD")
BASE_TITLE="${DIR_NAME}"
if [ -z "$SESSION_NAME" ]; then
SESSION_NAME="${BASE_TITLE}-1"
fi
# ── 构建 claude 启动参数 ─────────────────────────────────
CC_ARGS=(--ide --dangerously-skip-permissions --allow-dangerously-skip-permissions --effort max)
# 公共 skills 仓库(由 .env 的 SKILLS_DIR 配置,便于跨电脑迁移)
if [ -n "${SKILLS_DIR:-}" ]; then
CC_ARGS+=(--add-dir "$SKILLS_DIR")
fi
# ── 每日自动更新 ────────────────────────────────────────
UPGRADE_MARKER="${HOME}/.claude/.last-upgrade-date"
TODAY="$(date +%Y-%m-%d)"
if [ ! -f "$UPGRADE_MARKER" ] || [ "$(cat "$UPGRADE_MARKER" 2>/dev/null)" != "$TODAY" ]; then
echo "每日首次启动,检查 Claude Code 更新..."
if claude upgrade 2>&1; then
mkdir -p "$(dirname "$UPGRADE_MARKER")"
echo "$TODAY" > "$UPGRADE_MARKER"
else
echo "警告: claude upgrade 失败,跳过更新继续启动"
fi
fi
# ── 辅助函数:自动编号(列表中出现同名则递增)─────────────
# 用法: _auto_number "名字列表(换行分隔)" "基础名" → 输出下一个可用名
_auto_number() {
local list="$1"
local base="$2"
local name="$base"
local n=1
while echo "$list" | grep -qxF "$name"; do
n=$((n + 1))
name="${base}-${n}"
done
echo "$name"
}
# ════════════════════════════════════════════════════════════
# ── 启动 Claude Code(始终通过 tmux)──────────────────────
# ════════════════════════════════════════════════════════════
ORIG_PWD="$PWD"
WINDOW_NAME="$MODEL"
# ── 构建 -e 参数数组 ────────────────────────────────────
E_FLAGS=()
E_FLAGS+=(-e "ANTHROPIC_BASE_URL=$ANTHROPIC_BASE_URL")
E_FLAGS+=(-e "ANTHROPIC_AUTH_TOKEN=$ANTHROPIC_AUTH_TOKEN")
E_FLAGS+=(-e "ANTHROPIC_MODEL=$MODEL")
E_FLAGS+=(-e "ANTHROPIC_DEFAULT_OPUS_MODEL=$MODEL")
E_FLAGS+=(-e "ANTHROPIC_DEFAULT_HAIKU_MODEL=$MODEL")
E_FLAGS+=(-e "ANTHROPIC_DEFAULT_SONNET_MODEL=$MODEL")
E_FLAGS+=(-e "CLAUDE_CODE_SUBAGENT_MODEL=$MODEL")
E_FLAGS+=(-e "CC_CONTEXT_WINDOW=$CONTEXT_WINDOW")
E_FLAGS+=(-e "CLAUDE_CODE_NO_FLICKER=1")
if [ "$DISABLE_COMPACT" = "1" ]; then
E_FLAGS+=(-e "DISABLE_COMPACT=1")
E_FLAGS+=(-e "CLAUDE_CODE_MAX_CONTEXT_TOKENS=${MAX_CONTEXT_TOKENS:-$CONTEXT_WINDOW}")
else
E_FLAGS+=(-e "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=$COMPACT_PCT")
fi
if [ -n "${TMUX:-}" ]; then
# ── 已在 tmux 中:pane 标题 = session_model → 设置 env → 直接启动
TMUX_TITLE="${SESSION_NAME}_${MODEL}"
CC_ARGS+=(--name "$TMUX_TITLE")
echo "启动 Claude Code (provider: $CC_PROVIDER, 模型: $MODEL, 会话: $SESSION_NAME)"
tmux select-pane -T "$TMUX_TITLE" 2>/dev/null || true
# 传播环境变量到 tmux session(供子 pane/window 继承)
SID="$(tmux display-message -p '#{session_id}')"
tmux setenv -t "$SID" ANTHROPIC_BASE_URL "$ANTHROPIC_BASE_URL"
tmux setenv -t "$SID" ANTHROPIC_AUTH_TOKEN "$ANTHROPIC_AUTH_TOKEN"
tmux setenv -t "$SID" ANTHROPIC_MODEL "$MODEL"
tmux setenv -t "$SID" ANTHROPIC_DEFAULT_OPUS_MODEL "$MODEL"
tmux setenv -t "$SID" ANTHROPIC_DEFAULT_HAIKU_MODEL "$MODEL"
tmux setenv -t "$SID" ANTHROPIC_DEFAULT_SONNET_MODEL "$MODEL"
tmux setenv -t "$SID" CLAUDE_CODE_SUBAGENT_MODEL "$MODEL"
tmux setenv -t "$SID" CC_CONTEXT_WINDOW "$CONTEXT_WINDOW"
tmux setenv -t "$SID" CLAUDE_CODE_NO_FLICKER 1
if [ "$DISABLE_COMPACT" = "1" ]; then
tmux setenv -t "$SID" DISABLE_COMPACT 1
tmux setenv -t "$SID" CLAUDE_CODE_MAX_CONTEXT_TOKENS "${MAX_CONTEXT_TOKENS:-$CONTEXT_WINDOW}"
tmux setenv -u -t "$SID" CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 2>/dev/null || true
else
tmux setenv -t "$SID" CLAUDE_AUTOCOMPACT_PCT_OVERRIDE "$COMPACT_PCT"
tmux setenv -u -t "$SID" DISABLE_COMPACT 2>/dev/null || true
tmux setenv -u -t "$SID" CLAUDE_CODE_MAX_CONTEXT_TOKENS 2>/dev/null || true
fi
# 设置 pane 级属性(供 status_line 等读取)
tmux set-option -p @anthropic_model "$MODEL" 2>/dev/null || true
# 环境变量已在当前 shell 中 export,直接 exec
cd "$ORIG_PWD"
exec claude "${CC_ARGS[@]}"
else
# ── 不在 tmux 中:以目录名-序号创建独立 session(如 dit-1、dit-2
n=1
while tmux has-session -t "${BASE_TITLE}-${n}" 2>/dev/null; do
n=$((n + 1))
done
TMUX_SESSION="${BASE_TITLE}-${n}"
SESSION_NAME="$TMUX_SESSION"
TMUX_TITLE="${SESSION_NAME}_${MODEL}"
CC_ARGS+=(--name "$TMUX_TITLE")
echo "启动 Claude Code (provider: $CC_PROVIDER, 模型: $MODEL, tmux session: $TMUX_SESSION)"
# 构建 claude 启动命令
CC_CMD="claude"
for arg in "${CC_ARGS[@]}"; do
CC_CMD+=" $arg"
done
BASH_WRAPPER="if ! command -v claude &>/dev/null; then
echo '错误: claude 命令未找到'
echo -n '按 Enter 退出...'; read
exit 1
fi
exec ${CC_CMD}"
# 创建独立 tmux sessionsession 名 = MODEL 名)
tmux new-session -d -s "$TMUX_SESSION" -n "$WINDOW_NAME" -c "$ORIG_PWD" \
"${E_FLAGS[@]}" bash -c "$BASH_WRAPPER"
# 设置 pane 标题
tmux select-pane -t "$TMUX_SESSION:$WINDOW_NAME" -T "$TMUX_TITLE" 2>/dev/null || true
# ── tmux 会话级默认配置 ──────────────────────────────
# 参考: https://gitea.szis.com.cn/isos/team/src/branch/trunk/team/tmux.md
_apply_tmux_defaults() {
local sess="$1"
# 基础选项
tmux set-option -t "$sess" mouse on 2>/dev/null || true
tmux set-option -t "$sess" base-index 1 2>/dev/null || true
# tmux set-option -t "$sess" default-terminal "screen-256color" 2>/dev/null || true
tmux set-option -t "$sess" escape-time 0 2>/dev/null || true
tmux set-option -t "$sess" history-limit 50000 2>/dev/null || true
tmux set-option -t "$sess" set-titles on 2>/dev/null || true
tmux set-option -t "$sess" focus-events on 2>/dev/null || true
tmux set-option -t "$sess" set-clipboard on 2>/dev/null || true
tmux set-option -t "$sess" renumber-windows on 2>/dev/null || true
# 状态栏
tmux set-option -t "$sess" status-left "#S |" 2>/dev/null || true
tmux set-option -t "$sess" status-left-length 20 2>/dev/null || true
tmux set-option -t "$sess" status-right "%Y-%m-%d %H:%M" 2>/dev/null || true
tmux set-option -t "$sess" status-right-length 20 2>/dev/null || true
# 窗口选项
tmux set-window-option -t "$sess" pane-base-index 1 2>/dev/null || true
tmux set-window-option -t "$sess" mode-keys vi 2>/dev/null || true
tmux set-window-option -t "$sess" aggressive-resize on 2>/dev/null || true
# 存储 provider/model 元信息(供 --list 查询)
tmux set-option -t "$sess" @cc_provider "$CC_PROVIDER" 2>/dev/null || true
tmux set-option -t "$sess" @cc_model "$MODEL" 2>/dev/null || true
}
_apply_tmux_defaults "$TMUX_SESSION"
# 附加到会话(前台运行)
tmux attach-session -t "$TMUX_SESSION"
fi