tmuxclihook 0.3.7 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmuxclihook",
3
- "version": "0.3.7",
3
+ "version": "0.4.1",
4
4
  "description": "交互式 TUI 安装器:环境侦测、AI CLI 侦测、tmux-ai-status hooks 装/卸/修、TPM 软链校验",
5
5
  "type": "module",
6
6
  "bin": {
@@ -112,6 +112,52 @@ _clear_pane_id() {
112
112
  [ -n "$SESSION_ID" ] && rm -f "$(_pane_dir)/pane-${SESSION_ID}"
113
113
  }
114
114
 
115
+ # --- cc-switch provider 标签 ---
116
+ # cc-switch(switch 命令)launch 时向 CLI 注入 CC_SWITCH_PROVIDER / CC_SWITCH_PROVIDER_ID,
117
+ # CLI 的 hooks 进程继承之;tmux-ai-status 入口把它们捕获进 pane option
118
+ # @ai_provider / @ai_provider_id。聚合侧在此读取并渲染彩色 provider 段。
119
+ # 颜色真源:~/.cc-switch/statusline-preferences.json(colors.claude / colors.codex
120
+ # 按 providerId 分桶)——与 cc-switch wrapper 状态栏标签同一真源,TUI `o` 改色
121
+ # 下一次 rebuild 即生效。显式值是 ANSI SGI 码(30-37/90-97),映射 tmux colourN
122
+ # (30-37 → 0-7,90-97 → 8-15);缺省 auto = FNV-1a(name)落在 cc-switch wrapper
123
+ # 同款 6 色 bright 调色板上。JS Math.imul 是 32 位截断乘;64 位精确积 & 0xFFFFFFFF
124
+ # 与之同余,纯 bash 可复刻(非 ASCII 名按字节遍历,与 JS 码点遍历 hash 可能不同,
125
+ # 只影响 auto 落点,非错误)。
126
+ _PROVIDER_PREFS_LINES=""
127
+ _PROVIDER_PREFS_LOADED=""
128
+ _provider_prefs_lines() {
129
+ if [ -z "$_PROVIDER_PREFS_LINES" ] && [ -z "$_PROVIDER_PREFS_LOADED" ]; then
130
+ _PROVIDER_PREFS_LOADED=1
131
+ local f="${HOME}/.cc-switch/statusline-preferences.json"
132
+ if [ -f "$f" ]; then
133
+ # claude/codex 两桶浅合并:providerId 是 uuid,跨桶不冲突
134
+ _PROVIDER_PREFS_LINES=$(jq -r '((.colors.claude // {}) + (.colors.codex // {})) | to_entries[] | "\(.key)=\(.value)"' "$f" 2>/dev/null)
135
+ fi
136
+ fi
137
+ printf '%s' "$_PROVIDER_PREFS_LINES"
138
+ }
139
+
140
+ _provider_tag_colour() {
141
+ local id="$1" name="$2" v=""
142
+ if [ -n "$id" ]; then
143
+ v=$(printf '%s\n' "$(_provider_prefs_lines)" | awk -F= -v id="$id" '$1==id{print $2; exit}')
144
+ fi
145
+ case "$v" in
146
+ 3[0-7]) echo $(( v - 30 )); return ;;
147
+ 9[0-7]) echo $(( v - 82 )); return ;;
148
+ esac
149
+ # auto: FNV-1a 32 位
150
+ local hash=2166136261 i ch cp
151
+ for ((i=0; i<${#name}; i++)); do
152
+ ch="${name:$i:1}"
153
+ printf -v cp '%d' "'$ch"
154
+ hash=$(( (hash ^ cp) * 16777619 & 4294967295 ))
155
+ done
156
+ case $(( hash % 6 )) in
157
+ 0) echo 96 ;; 1) echo 92 ;; 2) echo 93 ;; 3) echo 95 ;; 4) echo 94 ;; 5) echo 91 ;;
158
+ esac
159
+ }
160
+
115
161
  # --- 状态聚合 ---
116
162
  # 扫描所有 attached session 的 pane,读取 @ai_pane_status,写入 @ai_all_status
117
163
  #
@@ -124,7 +170,7 @@ build_all_status() {
124
170
  cur_sess=""
125
171
  local _ai_names
126
172
  _ai_names=$(_collect_ai_process_names)
127
- while IFS='|' read -r pane_id session_name win_idx pane_idx claude_status _attached _created _entered cur_cmd; do
173
+ while IFS='|' read -r pane_id session_name win_idx pane_idx claude_status _attached _created _entered cur_cmd prov_name prov_id; do
128
174
  local pane_status="$claude_status"
129
175
  if [ -z "$pane_status" ]; then
130
176
  # 无显式状态:若前台是 AI 进程(codex 首个 turn 前空窗期),补 idle。
@@ -149,6 +195,12 @@ build_all_status() {
149
195
  status_block="#[bg=${STATUS_COLOR},fg=#282A36] ${pane_status} #[bg=default,fg=default]"
150
196
  fi
151
197
  local seg="${panel_block}${status_block}"
198
+ # cc-switch provider 段:有 @ai_provider 才显示(非 switch 启动的 pane 无此 option)
199
+ if [ -n "$prov_name" ]; then
200
+ local prov_colour
201
+ prov_colour=$(_provider_tag_colour "$prov_id" "$prov_name")
202
+ seg="${seg}#[fg=colour${prov_colour}][${prov_name}] #[fg=default]"
203
+ fi
152
204
  if [ "$session_name" != "$cur_sess" ]; then
153
205
  ALL="${ALL:+$ALL }${session_block}${seg}"
154
206
  cur_sess="$session_name"
@@ -160,7 +212,7 @@ build_all_status() {
160
212
  # 自指 switch 由 handler 的 per-client prev 对比滤除)
161
213
  # ② session_created(无进入记录时回退创建序)。不用 session_last_attached——
162
214
  # tmux 的 server_client_set_session 无条件刷新该时间戳(自指 switch 也算),污染排序。
163
- done < <(tmux list-panes -a -F "#{pane_id}|#{session_name}|#{window_index}|#{pane_index}|#{@ai_pane_status}|#{session_attached}|#{session_created}|#{@ai_entered_time}|#{pane_current_command}" 2>/dev/null | awk -F'|' -v OFS='|' '$6>0{if($8=="")$8=$7; print}' | sort -t'|' -k8,8n -k7,7n -k2,2 -k3,3n -k4,4n)
215
+ done < <(tmux list-panes -a -F "#{pane_id}|#{session_name}|#{window_index}|#{pane_index}|#{@ai_pane_status}|#{session_attached}|#{session_created}|#{@ai_entered_time}|#{pane_current_command}|#{@ai_provider}|#{@ai_provider_id}" 2>/dev/null | awk -F'|' -v OFS='|' '$6>0{if($8=="")$8=$7; print}' | sort -t'|' -k8,8n -k7,7n -k2,2 -k3,3n -k4,4n)
164
216
  }
165
217
 
166
218
  # --- Pending 集合管理(PreToolUse / PermissionRequest 配对)---
@@ -28,6 +28,23 @@ fi
28
28
  _save_pane_id
29
29
  _maybe_cleanup_stale
30
30
 
31
+ # cc-switch 注入的 provider 标签(launch env,CLI 的 hooks 进程继承)→
32
+ # per-pane option,供 build_all_status 聚合渲染。**仅 codex 捕获**:claude 的
33
+ # provider 标签由 wrapper 在 CLI 内的 statusline 显示,tmux 状态栏刻意不重复
34
+ # 渲染——claude/opencode 的事件一律走清理分支(顺带清掉同 pane 之前的残留)。
35
+ # codex 无 env(非 switch 启动)同样清理。env 随 CLI 进程定死,幂等重写无害。
36
+ if [ -n "$TMUX_PANE" ]; then
37
+ if [ "$TOOL_ID" = "codex" ] && [ -n "$CC_SWITCH_PROVIDER" ]; then
38
+ tmux set-option -pt "$TMUX_PANE" @ai_provider "$CC_SWITCH_PROVIDER" 2>/dev/null || true
39
+ if [ -n "$CC_SWITCH_PROVIDER_ID" ]; then
40
+ tmux set-option -pt "$TMUX_PANE" @ai_provider_id "$CC_SWITCH_PROVIDER_ID" 2>/dev/null || true
41
+ fi
42
+ else
43
+ tmux set-option -pt "$TMUX_PANE" -u @ai_provider 2>/dev/null || true
44
+ tmux set-option -pt "$TMUX_PANE" -u @ai_provider_id 2>/dev/null || true
45
+ fi
46
+ fi
47
+
31
48
  _pane_loc=""
32
49
  if [ -n "$TMUX_PANE" ]; then
33
50
  _pane_loc=$(tmux display-message -pt "$TMUX_PANE" -p "#{session_name}:#{window_index}.#{pane_index}" 2>/dev/null)