@zmainer/dsh-wx-bridge 1.1.4 → 1.1.6

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/README.md CHANGED
@@ -229,7 +229,7 @@ echo "来自管道的长文本" | node "<dataDir>/wxpush.mjs" --stdin
229
229
  | Node | **`>=22.19.0`**(`package.json` 的 `engines`):会话文件是**多帧 zstd**,逐帧解压用到 `node:zlib` 的 `zstdDecompressSync`。桌面端自带运行时(本机实测 v26)与系统 Node(本机 v22.19)都验证过 |
230
230
  | 操作系统 | **Windows 已实测**(进程树终止用 `taskkill /T /F`;运行时入口探测含 `%LOCALAPPDATA%\Programs\*` 扫描、PID 复用判断)。macOS / Linux **未实测**:内核是纯 Node,但上述几处是 Windows 实现,跨平台请先跑 `node lib/kernel/bridge.mjs --selftest-runtime` |
231
231
  | 依赖 | **零运行时依赖**(只用 Node 内建模块);不依赖任何 `@deepseek-ai/*` 包(宿主能力通过 `ctx.inject` 取用,缺失即降级) |
232
- | 自测 | `--selftest-runtime`(运行时入口)/ `--selftest-approval`(审批卡与回复解析)/ `--selftest-acp-approval`(审批 ↔ ACP `session/request_permission` 的线上契约)/ **`--selftest-overlays`(叠层模板与生成物:预设一致 + 推送提示 + 缩进)** / `--selftest-outbox`(推送信箱)/ `--selftest-files` / `--selftest-inbound` / `--selftest-presets` |
232
+ | 自测 | **`--print-config`(只读:打印实际配置链)** / `--selftest-runtime`(运行时入口)/ `--selftest-approval`(审批卡与回复解析)/ `--selftest-acp-approval`(审批 ↔ ACP `session/request_permission` 的线上契约)/ **`--selftest-overlays`(叠层模板与生成物:预设一致 + 推送提示 + 缩进)** / `--selftest-outbox`(推送信箱)/ `--selftest-files` / `--selftest-inbound` / `--selftest-presets` |
233
233
 
234
234
  ## 常见问题 / Troubleshooting
235
235
 
@@ -266,6 +266,16 @@ ode_modules\@zmainer\dsh-wx-bridge` → 改名成 `...dsh-wx-bridge.bak` 更稳
266
266
 
267
267
  ## 最近变更
268
268
 
269
+ - **1.1.6**:修 **1.1.4 引入的回归** —— 1.1.4 把 `let chatOverlayPath` 的声明连同旧函数一起换掉了,
270
+ 于是**真的走到「对话档」时会抛 `ReferenceError: chatOverlayPath is not defined`**(写成 1.1.4 时自测
271
+ 只覆盖了纯函数与文本生成,没跑到"取叠层路径"这一步,所以没被发现)。补回声明并加 `--print-config` 的
272
+ `overlays.chatOverlay` 断言位:现在它会如实指向生成的 `acp-overlay-chat.gen.yml`(内含当前 `acp.permPreset`)。
273
+ - **1.1.5**:新增只读自检 `--print-config` —— 一条命令看清桥**实际认到**的配置链(dataDir / 宿主 home /
274
+ ACP home / 子进程 home / vault / 契约 / 预设 / 审批策略 / 权限预设 / 两个叠层路径 / 推送 CLI 与 outbox),
275
+ 不启动主循环、不抢实例锁、不发网络请求。多 home 环境下"我改的 config 是不是桥在用的那份"用它一眼可辨。
276
+ 运行手册侧同步记录了一条机制事实:ACP 的权限预设**自带审批策略**(`workspace-write → approval: ask`、
277
+ `danger-full-access → approval: never`,共同组成 `dsh-permission-presets` 里的预设),
278
+ 所以"把预设收紧"天然就会产生可被微信应答的审批。
269
279
  - **1.1.4**:修「生成物把新预设静默顶掉」——「对话档」的 ACP 叠层(`acp-overlay-chat.gen.yml`)是**磁盘缓存**,
270
280
  改 `acp.permPreset` 或模板后不重启桥就会继续用旧的(本机实测:模板已是 `workspace-write`,磁盘上仍是
271
281
  `danger-full-access` ⇒ 收紧预设被无声抵消)。现在每次生成都重写、不再依赖进程内缓存,
@@ -822,7 +822,7 @@ function presetKey(peer) {
822
822
  if (peer.acpMode === 'chat') return 'chat'
823
823
  return ACP_DEFAULT_PRESET
824
824
  }
825
- function overlayFor(key) {
825
+ function overlayFor(key) {
826
826
  if (key === 'chat') return ensureChatOverlay()
827
827
  if (!overlayCache.has(key)) overlayCache.set(key, ensurePresetOverlay(key) || '')
828
828
  return overlayCache.get(key) || ACP_PATCH
@@ -863,6 +863,8 @@ function ensurePushHelper() {
863
863
  * 规则:`defaultPreset:` 一行**无论写的是什么值**都换成当前 `acp.permPreset`;
864
864
  * 再按模板最后的缩进追加提示行(推送命令要给手机侧的 agent 看)。
865
865
  */
866
+ let chatOverlayPath = ''
867
+
866
868
  export function buildChatOverlayText(text, permPreset, hintLines) {
867
869
  const lines = String(text ?? '').split(NL)
868
870
  while (lines.length && !String(lines[lines.length - 1]).trim()) lines.pop()
@@ -879,7 +881,7 @@ export function buildChatOverlayText(text, permPreset, hintLines) {
879
881
  * 必须重启桥才会重写,否则老生成文件会把新预设**静默顶掉**(2026-09-24 实测踩过)。
880
882
  * 这里**每次都重写**(一次几毫秒):宁可多写一次,也不要让"磁盘上的旧生成物"成为隐形真源。
881
883
  */
882
- function ensureChatOverlay() {
884
+ function ensureChatOverlay() {
883
885
  const src = join(HERE, 'acp-overlay-chat.yml')
884
886
  let text = ''
885
887
  try { text = readFileSync(src, 'utf8') } catch { return src }
@@ -888,7 +890,6 @@ function ensureChatOverlay() {
888
890
  try {
889
891
  const f = join(STATE_DIR, 'acp-overlay-chat.gen.yml')
890
892
  writeFileSync(f, out)
891
- // 只在内容变了时记一行,避免每次 spawn 都刷日志
892
893
  if (!chatOverlayPath) log('chat-overlay-written', { file: f, permPreset: ACP_PERM_PRESET })
893
894
  chatOverlayPath = f
894
895
  return f
@@ -2206,6 +2207,21 @@ async function main() {
2206
2207
  process.exit(ok ? 0 : 1)
2207
2208
  }
2208
2209
 
2210
+ if (args.includes('--print-config')) {
2211
+ // 只读自检:把桥实际认到的配置链打出来(不启动主循环、不抢锁、不发网络)。
2212
+ // 用途:核对"我改的那份 config.json / 预设"是不是桥正在用的那份(多 home 环境下最容易搞错)。
2213
+ console.log('[print-config] ' + JSON.stringify({
2214
+ dataDir: STATE_DIR, cwd: CWD,
2215
+ hostHome: HOST_HOME || '(未指定)', acpHome: ACP_HOME, childHome: CHILD_HOME,
2216
+ vault: VAULT_PATH || '(未指定)', contract: CONTRACT_FILE,
2217
+ acp: { enabled: ACP_ENABLED, preset: ACP_CFG.preset || '(跟随宿主默认)', permPolicy: ACP_PERM,
2218
+ permPreset: ACP_PERM_PRESET, approvalTimeoutMs: APPROVAL_TIMEOUT_MS, patchAcp: ACP_CFG.patchAcp !== false },
2219
+ overlays: { presetOverlay: overlayFor(ACP_DEFAULT_PRESET), chatOverlay: ensureChatOverlay() },
2220
+ push: { cli: PUSH_CLI, outbox: OUTBOX_DIR },
2221
+ }, null, 1))
2222
+ process.exit(0)
2223
+ }
2224
+
2209
2225
  acquireLock()
2210
2226
  // 上次进程遗留的运行态任务:本轮一启动就标成 interrupted。
2211
2227
  // 否则 runningCount() 永远虚高,`while (runningCount() >= MAX_CONCURRENT_TASKS)` 会把新任务永久挡住。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zmainer/dsh-wx-bridge",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "type": "module",
5
5
  "main": "./lib/index.js",
6
6
  "dsh": {