tmuxclihook 0.5.13 → 0.5.14

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.5.13",
3
+ "version": "0.5.14",
4
4
  "description": "交互式 TUI 安装器:环境侦测、AI CLI 侦测、tmux-ai-status hooks 装/卸/修、TPM 软链校验",
5
5
  "type": "module",
6
6
  "bin": {
@@ -219,7 +219,8 @@ adapter_uninstall_hooks() {
219
219
  local stripped
220
220
  stripped=$(_codex_read_existing | _codex_strip_managed)
221
221
  if [ "$(printf '%s' "$stripped" | jq -c .)" = "{}" ]; then
222
- rm -f "$ADAPTER_HOOKS_FILE"
222
+ # 符号链接(cc-switch 实例共享真源)只删真实目标,保留链接
223
+ _install_remove_target "$ADAPTER_HOOKS_FILE"
223
224
  echo "Codex hooks uninstalled (removed empty $ADAPTER_HOOKS_FILE)"
224
225
  else
225
226
  _install_atomic_write "$stripped" "$ADAPTER_HOOKS_FILE"
@@ -225,7 +225,8 @@ adapter_install_hooks() {
225
225
  adapter_uninstall_hooks() {
226
226
  if [ -f "$ADAPTER_HOOKS_FILE" ]; then
227
227
  if grep -q "$_OPENCODE_MARKER" "$ADAPTER_HOOKS_FILE" 2>/dev/null; then
228
- rm -f "$ADAPTER_HOOKS_FILE"
228
+ # 符号链接只删真实目标,保留链接(与原子写一致)
229
+ _install_remove_target "$ADAPTER_HOOKS_FILE"
229
230
  echo "opencode plugin uninstalled (removed $ADAPTER_HOOKS_FILE)"
230
231
  else
231
232
  echo "opencode plugin: $ADAPTER_HOOKS_FILE 非本插件生成,跳过删除"
@@ -15,14 +15,45 @@ _install_require_jq() {
15
15
  fi
16
16
  }
17
17
 
18
- # 原子写入:mktemp 与目标同目录 → 同文件系统 → mv 原子。
18
+ # 解析符号链接到最终真实路径(不要求目标存在——悬空链接同样要解析)。
19
+ # 相对链接基于链接所在目录解析;循环/超深链(>40 层)返回 1,调用方回退原路径。
20
+ # 用途:cc-switch 为每个 codex provider 建独立 CODEX_HOME,并把 hooks.json 做成
21
+ # 指向 ~/.codex/hooks.json 的符号链接(所有实例共享同一真源)。mv 作用于链接路径
22
+ # 时只替换链接本身,因此写入必须解析到真实目标,否则实例与共享真源分叉。
23
+ _install_real_target() { # $1=路径 → stdout 最终路径
24
+ local p="$1" link n=0
25
+ while [ -L "$p" ]; do
26
+ n=$((n + 1))
27
+ [ "$n" -le 40 ] || return 1
28
+ link=$(readlink "$p" 2>/dev/null) || return 1
29
+ [ -n "$link" ] || return 1
30
+ case "$link" in
31
+ /*) p="$link" ;;
32
+ *) p="$(dirname "$p")/$link" ;;
33
+ esac
34
+ done
35
+ printf '%s\n' "$p"
36
+ }
37
+
38
+ # 原子写入:mktemp 与真实目标同目录 → 同文件系统 → mv 原子。
19
39
  # 避免与 AI CLI 并发写产生竞态导致 hooks 字段丢失。
40
+ # 符号链接先解析:临时文件建在真实目标目录,mv 写穿链接(保留链接本身)。
20
41
  _install_atomic_write() {
21
- local content="$1" target="$2" tmp
22
- mkdir -p "$(dirname "$target")" 2>/dev/null || true
23
- tmp=$(mktemp "$(dirname "$target")/.hooks.XXXXXX")
42
+ local content="$1" target="$2" tmp real
43
+ real=$(_install_real_target "$target") || real="$target"
44
+ mkdir -p "$(dirname "$real")" 2>/dev/null || true
45
+ tmp=$(mktemp "$(dirname "$real")/.hooks.XXXXXX")
24
46
  printf '%s\n' "$content" > "$tmp"
25
- mv -f "$tmp" "$target"
47
+ mv -f "$tmp" "$real"
48
+ }
49
+
50
+ # 删除写入目标(uninstall 清空时用):符号链接解析后只删真实目标,保留链接
51
+ # (指向悬空,下次 install 写穿即恢复共享)。直接 rm 链接会删掉链接本身,把
52
+ # 共享真源留在原地——其他实例仍被注册,语义与「卸载」矛盾。
53
+ _install_remove_target() { # $1=路径
54
+ local target="$1" real
55
+ real=$(_install_real_target "$target") || real="$target"
56
+ rm -f "$real"
26
57
  }
27
58
 
28
59
  # --- 卸载意图标记(suppression marker)---