tmuxclihook 0.2.0 → 0.2.2

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.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "交互式 TUI 安装器:环境侦测、AI CLI 侦测、tmux-ai-status hooks 装/卸/修、TPM 软链校验",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,9 +26,12 @@ ADAPTER_HOOKS_FILE="${CODEX_HOME:-$HOME/.codex}/hooks.json"
26
26
  ADAPTER_HAS_SESSION_END="false"
27
27
  # SessionStart 延迟到首个 turn
28
28
  ADAPTER_SESSION_START_TIMING="deferred"
29
- # PermissionRequest 不含 tool_use_id,而 Codex 支持并行工具。用 sentinel 保守保持 `!`,
30
- # 直到 Stop/UserPromptSubmit/SessionStart 清理,避免其他工具完成时漏报待审批。
29
+ # PermissionRequest 不含 tool_use_id,而 Codex 支持并行工具。核心会将请求绑定到同工具的
30
+ # pending PreToolUse ID;无法绑定时用 sentinel 保持 `!` 到 turn/session 边界。
31
31
  ADAPTER_HOLD_UNMATCHED_PERMISSION="true"
32
+ # request_permissions 直接弹出 Codex 权限 UI,但上游不会发送 PermissionRequest hook。
33
+ # 它仍发送可配对的 PreToolUse/PostToolUse,因此可在 PreToolUse 阶段精确进入审批态。
34
+ ADAPTER_PERMISSION_PRE_TOOL_NAMES="request_permissions"
32
35
 
33
36
  # 自修复/TUI 调用的安装脚本
34
37
  ADAPTER_INSTALLER="${_LIB_DIR}/install-codex-hooks.sh"
@@ -263,6 +263,31 @@ _add_pending_perm() {
263
263
  _release_lock
264
264
  }
265
265
 
266
+ # PermissionRequest 缺少 ID 时,将它绑定到最近的同工具、尚未绑定权限的 PreToolUse。
267
+ # Codex 的 Pre/PostToolUse 仍携带同一个 tool_use_id,因此批准后的 PostToolUse 可精确清除。
268
+ _bind_pending_perm_to_pre() {
269
+ local mark="$1" tool="$2"
270
+ BOUND_PERMISSION_ID=""
271
+ _acquire_lock || return 1
272
+ local pre; pre=$(_pending_pre_path)
273
+ local perm; perm=$(_pending_perm_path)
274
+ local id pending_tool rest
275
+ if [ -f "$pre" ]; then
276
+ while read -r id pending_tool rest; do
277
+ [ -n "$id" ] || continue
278
+ [ "$pending_tool" = "${tool:-?}" ] || continue
279
+ if ! awk -v id="$id" '$1 == id { found=1; exit } END { exit !found }' "$perm" 2>/dev/null; then
280
+ BOUND_PERMISSION_ID="$id"
281
+ fi
282
+ done < "$pre"
283
+ fi
284
+ if [ -n "$BOUND_PERMISSION_ID" ]; then
285
+ echo "${BOUND_PERMISSION_ID} ${mark} ${tool:-?} $(date +%s)" >> "$perm"
286
+ fi
287
+ _release_lock
288
+ [ -n "$BOUND_PERMISSION_ID" ]
289
+ }
290
+
266
291
  # 从 pending-pre 和 pending-perm 同时移除 id(配对清除)
267
292
  _remove_pending_id() {
268
293
  local id="$1"
@@ -85,9 +85,10 @@ case "$EVENT" in
85
85
  if [ -n "$TOOL_USE_ID" ]; then
86
86
  _add_pending_perm "$TOOL_USE_ID" "$STATUS" "$TOOL"
87
87
  elif [ "${ADAPTER_HOLD_UNMATCHED_PERMISSION:-false}" = "true" ]; then
88
- # Codex 的 PermissionRequest 无请求 ID。sentinel 不与任何 PostToolUse ID 配对,
89
- # 因而保守保持审批态,直到 turn/session 边界统一清理。
90
- _add_pending_perm "__unmatched_permission__" "$STATUS" "$TOOL"
88
+ # Codex 的 PermissionRequest 无请求 ID,但紧邻的 Pre/PostToolUse 有同一个 ID。
89
+ # 优先绑定该 ID,让批准后的 PostToolUse 恢复处理中;无匹配项时才保守兜底。
90
+ _bind_pending_perm_to_pre "$STATUS" "$TOOL" || \
91
+ _add_pending_perm "__unmatched_permission__" "$STATUS" "$TOOL"
91
92
  fi
92
93
  ;;
93
94
  PermissionResolved)
@@ -105,19 +106,28 @@ case "$EVENT" in
105
106
  TOOL_USE_ID=$(echo "$INPUT" | jq -r '.tool_use_id // ""' 2>/dev/null)
106
107
  INPUT_DIGEST=$(echo "$INPUT" | jq -c '.tool_input // null' 2>/dev/null)
107
108
  _add_pending_pre "$TOOL_USE_ID" "$TOOL"
108
- # Claude 的 PermReq 不带 tool_use_id,派生看不到审批态;用 LIVE_STATUS 兜底。
109
- # Codex sentinel 和 OpenCode request ID 则会直接从 pending 集合派生。
110
- LIVE_STATUS=$(_current_pane_status)
111
- case "$LIVE_STATUS" in
112
- "!"|"?") STATUS="$LIVE_STATUS" ;;
113
- *)
114
- if _derive_status_from_pending; then
115
- STATUS="$DERIVED"
116
- else
117
- STATUS=">"
118
- fi
119
- ;;
120
- esac
109
+ _permission_pre_tool=0
110
+ for _permission_tool in ${ADAPTER_PERMISSION_PRE_TOOL_NAMES:-}; do
111
+ [ "$TOOL" = "$_permission_tool" ] && { _permission_pre_tool=1; break; }
112
+ done
113
+ if [ "$_permission_pre_tool" = "1" ]; then
114
+ STATUS="!"
115
+ _add_pending_perm "$TOOL_USE_ID" "$STATUS" "$TOOL"
116
+ else
117
+ # Claude 的 PermReq 不带 tool_use_id,派生看不到审批态;用 LIVE_STATUS 兜底。
118
+ # Codex sentinel 和 OpenCode request ID 则会直接从 pending 集合派生。
119
+ LIVE_STATUS=$(_current_pane_status)
120
+ case "$LIVE_STATUS" in
121
+ "!"|"?") STATUS="$LIVE_STATUS" ;;
122
+ *)
123
+ if _derive_status_from_pending; then
124
+ STATUS="$DERIVED"
125
+ else
126
+ STATUS=">"
127
+ fi
128
+ ;;
129
+ esac
130
+ fi
121
131
  ;;
122
132
  PostToolUse|PostToolUseFailure)
123
133
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)