功能(ClaudeCode): 新增飞书联动工具链与会话管理增强
- 新增命令: lark-delegate(跨项目委派)、lark-inbox(收件箱)、lark-me(自发送)、stop(任务收尾) - 新增工具: lark-consumer/consumer-ensure/inbox-check(飞书事件实时消费与会话隔离)、tmux-monitor(监控面板) - runcc.sh 增加 --list/--kill/--send 操作模式与多会话自增命名 - CLAUDE.md 增加强制要求(汇报格式、收尾通知、上下文压缩)
This commit is contained in:
+280
-39
@@ -3,6 +3,11 @@
|
||||
# 支持多 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)"
|
||||
@@ -33,6 +38,10 @@ 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
|
||||
@@ -44,11 +53,28 @@ while [ $# -gt 0 ]; do
|
||||
[ $# -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 " --name, -n <名称> Claude Code 会话显示名称"
|
||||
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"
|
||||
@@ -59,13 +85,18 @@ while [ $# -gt 0 ]; do
|
||||
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 --provider deepseek # DeepSeek + 默认模型"
|
||||
echo " runcc.sh -p deepseek dsf # DeepSeek + deepseek-v4-flash"
|
||||
echo " runcc.sh -l # 列出所有 CC 会话"
|
||||
echo " runcc.sh -k glm-52 # 终止 glm-52 会话"
|
||||
echo " runcc.sh -s glm-52 '你好' # 向 glm-52 发送消息"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
@@ -74,10 +105,65 @@ while [ $# -gt 0 ]; do
|
||||
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 动态解析 ─────────────────────────────────────
|
||||
# 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
|
||||
# 优先级:命令行 --provider > .env CC_PROVIDER > 默认 glm
|
||||
CC_PROVIDER="${PROVIDER_OVERRIDE:-${CC_PROVIDER:-glm}}"
|
||||
upper_provider="$(echo "$CC_PROVIDER" | tr '[:lower:]' '[:upper:]')"
|
||||
|
||||
@@ -115,13 +201,46 @@ else
|
||||
fi
|
||||
|
||||
# ── 更新 settings.json ──────────────────────────────────
|
||||
# 删除凭据、模型和窗口变量(由环境变量接管)
|
||||
# SETTINGS_FILE 路径由 .env 配置,默认 ~/.claude/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
|
||||
|
||||
# ── 模型解析 ──────────────────────────────────────────────
|
||||
@@ -154,27 +273,20 @@ 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
|
||||
|
||||
# ── tmux 模型传播(确保子 pane 能获取正确模型)─────────
|
||||
if [ -n "${TMUX:-}" ]; then
|
||||
SESSION_ID="$(tmux display-message -p '#{session_id}')"
|
||||
# ── 会话命名规则:目录名-序号(如 dit-1、szis-2)───────────
|
||||
DIR_NAME=$(basename "$PWD")
|
||||
BASE_TITLE="${DIR_NAME}"
|
||||
if [ -z "$SESSION_NAME" ]; then
|
||||
SESSION_NAME="${BASE_TITLE}-1"
|
||||
fi
|
||||
|
||||
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"
|
||||
# ── 构建 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
|
||||
|
||||
# ── 每日自动更新 ────────────────────────────────────────
|
||||
@@ -190,17 +302,146 @@ if [ ! -f "$UPGRADE_MARKER" ] || [ "$(cat "$UPGRADE_MARKER" 2>/dev/null)" != "$T
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 启动 Claude Code ────────────────────────────────────
|
||||
CC_ARGS=(--ide --dangerously-skip-permissions --allow-dangerously-skip-permissions --effort max)
|
||||
# CC_ARGS=(--verbose)
|
||||
# 公共 skills 仓库(由 .env 的 SKILLS_DIR 配置,便于跨电脑迁移)
|
||||
if [ -n "${SKILLS_DIR:-}" ]; then
|
||||
CC_ARGS+=(--add-dir "$SKILLS_DIR")
|
||||
# ── 辅助函数:自动编号(列表中出现同名则递增)─────────────
|
||||
# 用法: _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 "$SESSION_NAME" ]; then
|
||||
INITIAL_PROMPT="/rename $SESSION_NAME"
|
||||
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:+, 会话: $SESSION_NAME})"
|
||||
claude "${CC_ARGS[@]}" ${INITIAL_PROMPT:+"$INITIAL_PROMPT"}
|
||||
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 session(session 名 = 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
|
||||
|
||||
Reference in New Issue
Block a user