wezard 1.3.11 → 1.3.13

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.
@@ -83,6 +83,62 @@ case "$TRANSCRIPT_PATH" in
83
83
  */.codebuddy/*) CLI_BACKEND="codebuddy" ;;
84
84
  esac
85
85
 
86
+ # ── 权限模式解析 ────────────────────────────────────────────────────────
87
+ # 各家 CLI 对「完全跳过审批」的字面量不统一, 子代理更常报的是「继承」语义值而不是
88
+ # 父会话的实际模式:
89
+ # bypassPermissions Claude Code (--dangerously-skip-permissions 同义)
90
+ # fullAccess CodeBuddy / IDE 协议注入
91
+ # ignore|current|inherit|"" 「用父会话的模式」—— 本身不是决策
92
+ # 只认 bypassPermissions 一个字面量时, 后两类全掉进 daemon 长轮询, 而子代理那边
93
+ # 往往没人推卡 → 回 ask → CLI 弹出远端看不见的原生 picker (= 「danger skip all
94
+ # 没生效」的真实成因)。
95
+ is_bypass_mode() { case "$1" in bypassPermissions|fullAccess) return 0 ;; *) return 1 ;; esac; }
96
+ is_inherit_mode() { case "$1" in ""|ignore|current|inherit) return 0 ;; *) return 1 ;; esac; }
97
+
98
+ # 父会话模式档案。子代理是另起的 CLI 实例, 既拿不到父的 --permission-mode, 自己
99
+ # 的 permissions.defaultMode 通常也没写 —— payload 里只剩继承语义值或空。主线程
100
+ # 每次把实际模式写进 <stateDir>/modes/<sid>, 子代理按 transcript 反推父 sid 读回,
101
+ # 这是唯一能把父子模式对上的旁路。只有主线程 (无 agent_id) 才写, 否则子代理的
102
+ # default 会把父的 bypassPermissions 覆盖掉。
103
+ MODE_DIR="$STATE_DIR/modes"
104
+
105
+ # <projectDir>/<encodedCwd>/<parentSid>/subagents/agent-*.jsonl → parentSid;
106
+ # 主转录布局 <projectDir>/<sid>.jsonl → sid。与 daemon/approval.ts 的
107
+ # subagentParentOf 同源。
108
+ parent_sid() {
109
+ local p="$TRANSCRIPT_PATH"
110
+ case "$p" in
111
+ */subagents/agent-*.jsonl) p="${p%/subagents/*}"; printf '%s' "${p##*/}" ;;
112
+ */*.jsonl) p="${p##*/}"; printf '%s' "${p%.jsonl}" ;;
113
+ esac
114
+ }
115
+
116
+ record_mode() {
117
+ [[ -n "$SESSION_ID" && -n "$1" ]] || return 0
118
+ local f="$MODE_DIR/$SESSION_ID"
119
+ [[ "$(cat "$f" 2>/dev/null || true)" == "$1" ]] && return 0
120
+ mkdir -p "$MODE_DIR" 2>/dev/null || return 0
121
+ # 新会话首次落盘时顺手清掉一周前的旧档, 免得目录无限增长 (只在新建时跑一次)。
122
+ [[ -e "$f" ]] || find "$MODE_DIR" -type f -mtime +7 -delete 2>/dev/null || true
123
+ printf '%s' "$1" >"$f" 2>/dev/null || true
124
+ }
125
+
126
+ recall_mode() {
127
+ local sid m
128
+ for sid in "$SESSION_ID" "$(parent_sid)"; do
129
+ [[ -n "$sid" && -r "$MODE_DIR/$sid" ]] || continue
130
+ m=$(cat "$MODE_DIR/$sid" 2>/dev/null || true)
131
+ [[ -n "$m" ]] && { printf '%s' "$m"; return 0; }
132
+ done
133
+ }
134
+
135
+ EFFECTIVE_MODE="$PERMISSION_MODE"
136
+ if is_inherit_mode "$EFFECTIVE_MODE"; then
137
+ EFFECTIVE_MODE=$(recall_mode)
138
+ elif [[ -z "$AGENT_ID" ]]; then
139
+ record_mode "$EFFECTIVE_MODE"
140
+ fi
141
+
86
142
  # 权限模式短路: 只对用户主动选的"完全跳过"模式放掉, 其它一律走 daemon 发 IM
87
143
  # 卡, 让 wezard 远端用户能在 IM 上点决策。
88
144
  # - bypassPermissions: 用户已经主动选了"全跳", emit allow 直接放, 不打 daemon。
@@ -95,12 +151,16 @@ esac
95
151
  # 走卡 (远端用户的主动决策), 故任何 mode 都不在此短路。
96
152
  # WEZARD_HONOR_AUTO_MODE=0 关掉本段对齐行为。
97
153
  if [[ "$TOOL_NAME" != "AskUserQuestion" ]] && [[ "${WEZARD_HONOR_AUTO_MODE:-1}" != "0" ]]; then
98
- case "$PERMISSION_MODE" in
99
- bypassPermissions)
100
- emit "allow" "bypass-mode passthrough" ;;
101
- esac
154
+ if is_bypass_mode "$EFFECTIVE_MODE"; then
155
+ emit "allow" "bypass-mode passthrough ($EFFECTIVE_MODE)"
156
+ fi
102
157
  fi
103
158
 
159
+ # daemon 二次裁决用 (approval.ts 的 permission-mode 分支): 传解析后的模式而不是
160
+ # 原始字面量。killswitch 打开时不传 —— 那正是「别替我跳过」的意思。
161
+ MODE_FOR_DAEMON=""
162
+ [[ "${WEZARD_HONOR_AUTO_MODE:-1}" != "0" ]] && MODE_FOR_DAEMON="$EFFECTIVE_MODE"
163
+
104
164
  # ExitPlanMode 只是把 plan mode 的产出交给用户确认, 本地 CLI 会再弹一次原生
105
165
  # 确认框, 走 IM 审批纯属多此一举, 直接放行。
106
166
  # (codebuddy 更不走过这里: 实测它的 ExitPlanMode 完全由 interruption-service
@@ -182,10 +242,12 @@ build_body() {
182
242
  --arg rid "$RESUME_ID" \
183
243
  --arg aid "$AGENT_ID" \
184
244
  --arg aty "$AGENT_TYPE" \
245
+ --arg pm "$MODE_FOR_DAEMON" \
185
246
  '{session_id:$sid,tool_name:$tn,tool_input:$ti,cwd:$cwd,transcript_tail:$tail,transcript_path:$tp,cli_backend:$cb}
186
247
  + (if $rid == "" then {} else {resume_req_id:$rid} end)
187
248
  + (if $aid == "" then {} else {agent_id:$aid} end)
188
- + (if $aty == "" then {} else {agent_type:$aty} end)'
249
+ + (if $aty == "" then {} else {agent_type:$aty} end)
250
+ + (if $pm == "" then {} else {permission_mode:$pm} end)'
189
251
  }
190
252
 
191
253
  # drain 到进程真正退出之间还有 ~200ms。不等它先死就重投, 会打进这个将死的进程,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wezard",
3
- "version": "1.3.11",
3
+ "version": "1.3.13",
4
4
  "description": "Bridge Claude Code and WeCom: PreToolUse approval cards + bidirectional tmux session mirror with image paste",
5
5
  "type": "module",
6
6
  "license": "MIT",