@vrs-soft/wecom-aibot-mcp 3.4.6 → 3.4.7

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.
@@ -948,24 +948,50 @@ function registerChannelTools(server) {
948
948
  .describe('运行模式:channel=SSE推送(推荐),http=轮询(兼容)'),
949
949
  auto_approve_timeout: z.number().optional().default(600).describe('超时自动决策等待时间(秒,默认 600 即 10 分钟)'),
950
950
  }, async ({ agent_name, cc_id, robot_id, project_dir, mode, auto_approve_timeout }) => {
951
- // v3.3.2: 远端 daemon 看不到本地 .claude/wecom-aibot.json,无法走 existingConfig 复用 ccId 的路径。
952
- // 这里在 channel-server 本地读保存的 ccId,没有传入 cc_id 时自动塞进去 —— 避免每次 enter
953
- // 都因 stale registry entry 撞冲突,生成 商务机器人-2 / -3 之类的奇怪 ccId。
954
- const effectiveProjectDir = project_dir || process.cwd();
955
- let effectiveCcId = cc_id;
956
- if (!effectiveCcId) {
957
- const saved = loadWechatModeConfig(effectiveProjectDir);
958
- if (saved?.ccId) {
959
- effectiveCcId = saved.ccId;
960
- logger.info('reuse saved ccId from local wecom-aibot.json', { projectDir: effectiveProjectDir, ccId: saved.ccId });
961
- }
951
+ // ============================================
952
+ // v3.4.7: 权威源 = 运行时独立派生,LLM 传入不采用
953
+ // ============================================
954
+ // 根因:LLM 会传业务名/记忆里的字面量当 cc_id("集装箱配比优化系统"),
955
+ // 甚至同时篡改 project_dir basename 匹配绕过校验
956
+ // 修复:channel-server 是 Claude Code stdio 子进程,process.cwd() 由 Claude Code
957
+ // 启动时用户 cd 到项目目录设定,LLM 通过 tool-call 改不了 cwd
958
+ // → 强制用 cwd 派生权威 project_dir 和 cc_id
959
+ // LLM 传入的 cc_id / project_dir / agent_name 只 log 不采用
960
+ // 边界:这只挡"LLM 篡改"(当前威胁),挡不了"用户在非项目目录启动 claude"
961
+ // 后者要用 MCP roots capability(后续 v3.4.8)
962
+ const authProjectDir = process.cwd();
963
+ const authCcId = path.basename(authProjectDir);
964
+ const authAgentName = authCcId;
965
+ // 观测 LLM 有没有企图伪造
966
+ if (cc_id && cc_id !== authCcId) {
967
+ logger.warn?.('LLM cc_id ignored', { llmCcId: cc_id, authCcId, authProjectDir });
968
+ }
969
+ if (project_dir && project_dir !== authProjectDir) {
970
+ logger.warn?.('LLM project_dir ignored', { llmProjectDir: project_dir, authProjectDir });
971
+ }
972
+ if (agent_name && agent_name !== authAgentName) {
973
+ logger.warn?.('LLM agent_name ignored', { llmAgentName: agent_name, authAgentName });
974
+ }
975
+ // 只有 saved config 是本地文件(Claude Code 启动前就存在),是可信源,但要跟 auth 值一致才用
976
+ const saved = loadWechatModeConfig(authProjectDir);
977
+ let effectiveCcId = authCcId; // 默认 auth 值
978
+ if (saved?.ccId && saved.ccId === authCcId) {
979
+ // 一致:正常复用
980
+ effectiveCcId = saved.ccId;
981
+ }
982
+ else if (saved?.ccId && saved.ccId !== authCcId) {
983
+ // 本地 config 存了错值(可能是老版本 LLM 拍脑袋写的)→ 强制忽略,改用 auth 值
984
+ logger.warn?.('saved wecom-aibot.json 里 ccId 跟 auth 不一致,强制覆盖', {
985
+ savedCcId: saved.ccId,
986
+ authCcId,
987
+ });
962
988
  }
963
- // 转发请求
989
+ // 转发请求(永远用 auth 派生值,无视 LLM 传入)
964
990
  const result = await forwardToHttpMcp('enter_headless_mode', {
965
- agent_name,
991
+ agent_name: authAgentName,
966
992
  cc_id: effectiveCcId,
967
- robot_id,
968
- project_dir: effectiveProjectDir,
993
+ robot_id, // robot_id 保留(要走 fail-closed 让用户选,见 SKILL.md)
994
+ project_dir: authProjectDir,
969
995
  mode,
970
996
  auto_approve_timeout,
971
997
  });
@@ -977,12 +1003,12 @@ function registerChannelTools(server) {
977
1003
  const parsed = JSON.parse(content[0].text);
978
1004
  if (parsed.ccId) {
979
1005
  logger.info('Got ccId, connecting SSE', { ccId: parsed.ccId, mode });
980
- // 保存连接参数供重连复用
981
- sseRobotId = robot_id || parsed.robotName;
982
- sseProjectDir = project_dir || process.cwd();
1006
+ // v3.4.7: 保存 auth 派生值(不用 LLM 传入的 robot_id / project_dir),SSE 重连时用
1007
+ sseRobotId = parsed.robotName; // daemon 返回的权威值
1008
+ sseProjectDir = authProjectDir; // channel-server 派生的 auth 值
983
1009
  connectSSE(parsed.ccId);
984
1010
  // Channel 模式:在本地项目写入 PermissionRequest hook
985
- const localProjectDir = project_dir || process.cwd();
1011
+ const localProjectDir = authProjectDir; // v3.4.7: 用 auth 值
986
1012
  // v3.4.0: 先确保 ~/.wecom-aibot-mcp/permission-hook.mjs 存在
987
1013
  // (addPermissionHook 只往项目 settings.json 写命令,不装文件;
988
1014
  // 没装文件的话 Claude TUI 执行 hook 命令会 ENOENT)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vrs-soft/wecom-aibot-mcp",
3
- "version": "3.4.6",
3
+ "version": "3.4.7",
4
4
  "description": "企业微信智能机器人 MCP 客户端 - 连接 wecom-aibot-server daemon",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",