@vrs-soft/wecom-aibot-mcp 3.4.5 → 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.
- package/dist/channel-server.js +48 -25
- package/package.json +1 -1
package/dist/channel-server.js
CHANGED
|
@@ -604,12 +604,9 @@ function registerChannelTools(server) {
|
|
|
604
604
|
target_user: z.string().optional().describe('目标用户/群 ID(可选)'),
|
|
605
605
|
cc_id: z.string().describe('CC 唯一标识(enter_headless_mode 返回的 ccId)'),
|
|
606
606
|
}, async ({ content, target_user, cc_id }) => {
|
|
607
|
-
//
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
return {
|
|
611
|
-
content: [{ type: 'text', text: '✅ 消息已发送' }],
|
|
612
|
-
};
|
|
607
|
+
// v3.4.6: 不再硬编码 ✅,直接返回 daemon 端真实结果(含 ✅ 或错误信息)
|
|
608
|
+
// 防止 send 失败时骗 agent,也让 LiuYang 之前遇到的"骗人 UX bug"消失
|
|
609
|
+
return await forwardToHttpMcp('send_message', { content, target_user, cc_id });
|
|
613
610
|
});
|
|
614
611
|
// ============================================
|
|
615
612
|
// 工具 2: 心跳检查(HTTP 模式)
|
|
@@ -951,24 +948,50 @@ function registerChannelTools(server) {
|
|
|
951
948
|
.describe('运行模式:channel=SSE推送(推荐),http=轮询(兼容)'),
|
|
952
949
|
auto_approve_timeout: z.number().optional().default(600).describe('超时自动决策等待时间(秒,默认 600 即 10 分钟)'),
|
|
953
950
|
}, async ({ agent_name, cc_id, robot_id, project_dir, mode, auto_approve_timeout }) => {
|
|
954
|
-
//
|
|
955
|
-
//
|
|
956
|
-
//
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
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
|
+
});
|
|
965
988
|
}
|
|
966
|
-
//
|
|
989
|
+
// 转发请求(永远用 auth 派生值,无视 LLM 传入)
|
|
967
990
|
const result = await forwardToHttpMcp('enter_headless_mode', {
|
|
968
|
-
agent_name,
|
|
991
|
+
agent_name: authAgentName,
|
|
969
992
|
cc_id: effectiveCcId,
|
|
970
|
-
robot_id,
|
|
971
|
-
project_dir:
|
|
993
|
+
robot_id, // robot_id 保留(要走 fail-closed 让用户选,见 SKILL.md)
|
|
994
|
+
project_dir: authProjectDir,
|
|
972
995
|
mode,
|
|
973
996
|
auto_approve_timeout,
|
|
974
997
|
});
|
|
@@ -980,12 +1003,12 @@ function registerChannelTools(server) {
|
|
|
980
1003
|
const parsed = JSON.parse(content[0].text);
|
|
981
1004
|
if (parsed.ccId) {
|
|
982
1005
|
logger.info('Got ccId, connecting SSE', { ccId: parsed.ccId, mode });
|
|
983
|
-
//
|
|
984
|
-
sseRobotId =
|
|
985
|
-
sseProjectDir =
|
|
1006
|
+
// v3.4.7: 保存 auth 派生值(不用 LLM 传入的 robot_id / project_dir),SSE 重连时用
|
|
1007
|
+
sseRobotId = parsed.robotName; // daemon 返回的权威值
|
|
1008
|
+
sseProjectDir = authProjectDir; // channel-server 派生的 auth 值
|
|
986
1009
|
connectSSE(parsed.ccId);
|
|
987
1010
|
// Channel 模式:在本地项目写入 PermissionRequest hook
|
|
988
|
-
const localProjectDir =
|
|
1011
|
+
const localProjectDir = authProjectDir; // v3.4.7: 用 auth 值
|
|
989
1012
|
// v3.4.0: 先确保 ~/.wecom-aibot-mcp/permission-hook.mjs 存在
|
|
990
1013
|
// (addPermissionHook 只往项目 settings.json 写命令,不装文件;
|
|
991
1014
|
// 没装文件的话 Claude TUI 执行 hook 命令会 ENOENT)
|