mirror of
https://github.com/HappyLifeOk/cc-3-8-x-mcp.git
synced 2026-08-20 13:37:13 +00:00
[router] 修复: editor 慢启动后激活的工具不推送给 claude
discover 周期重扫已有,但两个 bug 让 claude 永远停在初次 tools/list 旧快照: 1. 已缓存 editor 不 re-probe(146 行 continue)——大项目 editor 慢启动(builder worker 没就绪)首次只 probe 到部分工具,asset-db 就绪后工具激活也不刷新 2. 声明 capabilities.tools.listChanged=true 却从不真发 notifications/tools/list_changed 修复:每周期 re-probe(probe 失败保留旧缓存)+ 工具签名变化时发 list_changed (clientInitialized 后)。spawn router 实测 tools/list 正确暴露 33 工具(25 forest__ + 8 router)。
This commit is contained in:
+38
-3
@@ -139,13 +139,17 @@ function sanitizeShortName(name) {
|
|||||||
async function discover() {
|
async function discover() {
|
||||||
var entries = scanRegistry();
|
var entries = scanRegistry();
|
||||||
var seen = new Set();
|
var seen = new Set();
|
||||||
|
var beforeSig = toolListSignature(); // 改动前的工具签名,末尾比对决定是否通知 claude
|
||||||
for (var i = 0; i < entries.length; i++) {
|
for (var i = 0; i < entries.length; i++) {
|
||||||
var info = entries[i];
|
var info = entries[i];
|
||||||
var key = info.url;
|
var key = info.url;
|
||||||
seen.add(key);
|
seen.add(key);
|
||||||
if (editors.has(key)) continue; // 已知,不重复 probe
|
// 已缓存的 editor 也 re-probe:大项目 editor 慢启动(builder worker 没就绪)时,
|
||||||
|
// 首次 probe 只拿到部分/空工具;之后 asset-db 就绪、业务工具全激活,必须重新 probe 刷新,
|
||||||
|
// 否则 claude 永远看不到后激活的工具(如 forest__preview_refresh_and_reload)。
|
||||||
|
var existing = editors.get(key);
|
||||||
var tools = await probeEditor(info);
|
var tools = await probeEditor(info);
|
||||||
if (tools == null) continue;
|
if (tools == null) continue; // probe 失败:保留旧缓存(editor 可能临时忙/重启中),不覆盖
|
||||||
var resources = await probeEditorResources(info);
|
var resources = await probeEditorResources(info);
|
||||||
editors.set(key, {
|
editors.set(key, {
|
||||||
baseShortName: sanitizeShortName(info.projectShortName),
|
baseShortName: sanitizeShortName(info.projectShortName),
|
||||||
@@ -157,7 +161,11 @@ async function discover() {
|
|||||||
resources: resources,
|
resources: resources,
|
||||||
lastProbed: Date.now(),
|
lastProbed: Date.now(),
|
||||||
});
|
});
|
||||||
logErr('discovered editor', info.projectShortName, 'pid=' + info.pid, info.url, tools.length + ' tools');
|
if (!existing) {
|
||||||
|
logErr('discovered editor', info.projectShortName, 'pid=' + info.pid, info.url, tools.length + ' tools');
|
||||||
|
} else if (existing.tools.length !== tools.length) {
|
||||||
|
logErr('editor tools updated', info.projectShortName, existing.tools.length + ' → ' + tools.length + ' tools');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 清理已消失的
|
// 清理已消失的
|
||||||
for (var key2 of Array.from(editors.keys())) {
|
for (var key2 of Array.from(editors.keys())) {
|
||||||
@@ -169,6 +177,32 @@ async function discover() {
|
|||||||
}
|
}
|
||||||
// shortName 撞名去重(多编辑器 projectShortName 相同时,否则 tool 前缀冲突会把请求路由到错的编辑器)
|
// shortName 撞名去重(多编辑器 projectShortName 相同时,否则 tool 前缀冲突会把请求路由到错的编辑器)
|
||||||
dedupeShortNames();
|
dedupeShortNames();
|
||||||
|
// 工具列表变化(编辑器增减 / 某编辑器工具数从不全变全)→ 通知 claude 重新拉 tools/list。
|
||||||
|
// 否则 claude 停在初次 tools/list 的旧快照:editor 慢启动时初次只暴露 router 自带工具,
|
||||||
|
// 后激活的 forest__ 业务工具 claude 永远拿不到(capabilities.tools.listChanged 声明了但从不真发是历史 bug)。
|
||||||
|
if (toolListSignature() !== beforeSig) {
|
||||||
|
notifyToolsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 工具列表签名:editors 的 shortName:工具数 排序拼接。变化即代表暴露给 claude 的聚合工具列表变了。 */
|
||||||
|
function toolListSignature() {
|
||||||
|
var parts = [];
|
||||||
|
for (var ed of editors.values()) {
|
||||||
|
parts.push(ed.shortName + ':' + ed.tools.length);
|
||||||
|
}
|
||||||
|
parts.sort();
|
||||||
|
return parts.join('|');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 标记 claude 已完成 MCP initialize 握手——之前发 list_changed 没意义(client 尚未就绪)。 */
|
||||||
|
var clientInitialized = false;
|
||||||
|
|
||||||
|
/** 发 MCP notifications/tools/list_changed,让 claude 重新请求 tools/list 拿最新聚合列表。 */
|
||||||
|
function notifyToolsChanged() {
|
||||||
|
if (!clientInitialized) return;
|
||||||
|
send({ jsonrpc: '2.0', method: 'notifications/tools/list_changed' });
|
||||||
|
logErr('sent notifications/tools/list_changed (工具列表已变化)');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -311,6 +345,7 @@ async function handleMessage(msg) {
|
|||||||
break;
|
break;
|
||||||
case 'initialized':
|
case 'initialized':
|
||||||
case 'notifications/initialized':
|
case 'notifications/initialized':
|
||||||
|
clientInitialized = true; // 握手完成;此后 discover 检测到工具变化才发 list_changed
|
||||||
if (id == null) return;
|
if (id == null) return;
|
||||||
result = {};
|
result = {};
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user