@vrs-soft/wecom-aibot-mcp 3.4.0 → 3.4.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.
@@ -14,7 +14,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
14
14
  import { z } from 'zod';
15
15
  import * as fs from 'fs';
16
16
  import * as path from 'path';
17
- import { VERSION, installSkill } from './config-wizard.js';
17
+ import { VERSION, installSkill, ensureHookFiles } from './config-wizard.js';
18
18
  import { addPermissionHook, registerActiveProject, unregisterActiveProject, updateWechatModeConfig, loadWechatModeConfig } from './project-config.js';
19
19
  import { findClaudePid } from './platform.js';
20
20
  import { logger } from './logger.js';
@@ -860,6 +860,15 @@ function registerChannelTools(server) {
860
860
  connectSSE(parsed.ccId);
861
861
  // Channel 模式:在本地项目写入 PermissionRequest hook
862
862
  const localProjectDir = project_dir || process.cwd();
863
+ // v3.4.0: 先确保 ~/.wecom-aibot-mcp/permission-hook.mjs 存在
864
+ // (addPermissionHook 只往项目 settings.json 写命令,不装文件;
865
+ // 没装文件的话 Claude TUI 执行 hook 命令会 ENOENT)
866
+ try {
867
+ ensureHookFiles();
868
+ }
869
+ catch (e) {
870
+ logger.error('ensureHookFiles 失败', { error: String(e) });
871
+ }
863
872
  const hookResult = addPermissionHook(localProjectDir);
864
873
  logger.info('本地 PermissionRequest hook 已写入', { path: hookResult.path, success: hookResult.success });
865
874
  // 注册 Claude TUI 的 PID(不能用 process.ppid,npx 部署时 ppid 是 npx 不是 Claude)
@@ -1063,6 +1072,18 @@ function registerChannelTools(server) {
1063
1072
  */
1064
1073
  export async function startChannelServer() {
1065
1074
  logChannel('Starting Channel MCP Proxy');
1075
+ // v3.4.2: 启动即装 hook 文件(幂等)。
1076
+ // 防止"已在微信模式 + npx 升级"这种场景:项目 settings.json 已经指向
1077
+ // ~/.wecom-aibot-mcp/permission-hook.mjs,但因为没人重新调 enter_headless_mode,
1078
+ // ensureHookFiles 永远不跑 → 文件不存在 → hook ENOENT 静默放行。
1079
+ // 这里每次 TUI spawn channel-server 都跑一次,确保文件永远是最新版且存在。
1080
+ try {
1081
+ ensureHookFiles();
1082
+ logChannel('Hook 文件已确保安装(启动时幂等检查)');
1083
+ }
1084
+ catch (e) {
1085
+ logChannel('ensureHookFiles 启动时失败', { error: String(e) });
1086
+ }
1066
1087
  // 创建 MCP Server
1067
1088
  mcpServer = new McpServer({
1068
1089
  name: 'wecom-aibot-channel',
@@ -5,6 +5,7 @@ export declare function deleteHook(): void;
5
5
  export declare function deleteSkills(): void;
6
6
  export declare function uninstall(): void;
7
7
  export declare function ensureHookInstalled(): void;
8
+ export declare function ensureHookFiles(): void;
8
9
  export type InstallMode = 'channel-only' | 'remote' | 'remote-channel';
9
10
  export declare function getInstalledMode(): {
10
11
  mode?: InstallMode;
@@ -266,6 +266,13 @@ export function ensureHookInstalled() {
266
266
  writeMcpPermissions();
267
267
  writeStopHookScript();
268
268
  }
269
+ // v3.4.0: 只装 hook 文件本身(不动 ~/.claude/settings.local.json),
270
+ // 供 channel-server enter_headless_mode 在写项目级 settings.json 前
271
+ // 确保 ~/.wecom-aibot-mcp/permission-hook.mjs 真实存在
272
+ export function ensureHookFiles() {
273
+ writeHookScript();
274
+ writeStopHookScript();
275
+ }
269
276
  // 读取上次安装的模式 + 远程参数(来自 version.json)
270
277
  export function getInstalledMode() {
271
278
  if (!fs.existsSync(VERSION_FILE))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vrs-soft/wecom-aibot-mcp",
3
- "version": "3.4.0",
3
+ "version": "3.4.2",
4
4
  "description": "企业微信智能机器人 MCP 客户端 - 连接 wecom-aibot-server daemon",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",