@blueking/bkui-knowledge 0.0.1-beta.10 → 0.0.1-beta.11
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/bin/bkui-knowledge.js +90 -12
- package/package.json +1 -1
package/bin/bkui-knowledge.js
CHANGED
|
@@ -26,14 +26,23 @@
|
|
|
26
26
|
* }
|
|
27
27
|
* }
|
|
28
28
|
*
|
|
29
|
+
* Claude Code(无需额外配置,自动从 MCP initialize 请求获取项目路径):
|
|
30
|
+
* {
|
|
31
|
+
* "bkui-knowledge": {
|
|
32
|
+
* "command": "npx",
|
|
33
|
+
* "args": ["-y", "@blueking/bkui-knowledge", "--ide=claude-code"]
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
29
37
|
* 参数说明:
|
|
30
38
|
* - 第一个非 -- 开头的参数: 项目路径
|
|
31
|
-
* - --ide=cursor|codebuddy: 指定目标 IDE(默认 cursor)
|
|
39
|
+
* - --ide=cursor|codebuddy|claude-code: 指定目标 IDE(默认 cursor)
|
|
32
40
|
*
|
|
33
41
|
* 项目路径传递方式(优先级从高到低):
|
|
34
42
|
* 1. 命令行参数: npx @blueking/bkui-knowledge /path/to/project
|
|
35
43
|
* 2. 环境变量: BKUI_PROJECT_ROOT=/path/to/project
|
|
36
|
-
* 3.
|
|
44
|
+
* 3. MCP initialize 请求中的 rootUri(Claude Code 等支持此协议的客户端)
|
|
45
|
+
* 4. 当前工作目录 (cwd)
|
|
37
46
|
*
|
|
38
47
|
* 更新机制:
|
|
39
48
|
* - skills 内置在 npm 包中
|
|
@@ -57,9 +66,20 @@ const IDE_CONFIGS = {
|
|
|
57
66
|
configDir: '.codebuddy',
|
|
58
67
|
skillsDir: '.codebuddy/skills',
|
|
59
68
|
versionFile: '.codebuddy/.bkui-knowledge-version'
|
|
69
|
+
},
|
|
70
|
+
'claude-code': {
|
|
71
|
+
name: 'Claude Code',
|
|
72
|
+
configDir: '.claude',
|
|
73
|
+
skillsDir: '.claude/skills',
|
|
74
|
+
versionFile: '.claude/.bkui-knowledge-version'
|
|
60
75
|
}
|
|
61
76
|
};
|
|
62
77
|
|
|
78
|
+
// 用于存储从 MCP initialize 请求获取的项目路径
|
|
79
|
+
let mcpRootUri = null;
|
|
80
|
+
// 标记是否已经同步过 skills
|
|
81
|
+
let skillsSynced = false;
|
|
82
|
+
|
|
63
83
|
// npm 包根目录
|
|
64
84
|
const PKG_ROOT = path.join(__dirname, '..');
|
|
65
85
|
|
|
@@ -95,7 +115,7 @@ function getIDEConfig() {
|
|
|
95
115
|
|
|
96
116
|
/**
|
|
97
117
|
* 获取用户项目根目录
|
|
98
|
-
* 优先级:命令行参数 > 环境变量 > cwd
|
|
118
|
+
* 优先级:命令行参数 > 环境变量 > MCP rootUri > cwd
|
|
99
119
|
*/
|
|
100
120
|
function getProjectRoot() {
|
|
101
121
|
// 1. 命令行参数: node bkui-knowledge.js /path/to/project (过滤掉 -- 开头的参数)
|
|
@@ -107,10 +127,34 @@ function getProjectRoot() {
|
|
|
107
127
|
if (process.env.BKUI_PROJECT_ROOT) {
|
|
108
128
|
return process.env.BKUI_PROJECT_ROOT;
|
|
109
129
|
}
|
|
110
|
-
// 3.
|
|
130
|
+
// 3. MCP initialize 请求中的 rootUri
|
|
131
|
+
if (mcpRootUri) {
|
|
132
|
+
return mcpRootUri;
|
|
133
|
+
}
|
|
134
|
+
// 4. 默认使用 cwd
|
|
111
135
|
return process.cwd();
|
|
112
136
|
}
|
|
113
137
|
|
|
138
|
+
/**
|
|
139
|
+
* 从 file:// URI 提取路径
|
|
140
|
+
* @param {string} uri - file:// URI
|
|
141
|
+
* @returns {string} 文件系统路径
|
|
142
|
+
*/
|
|
143
|
+
function uriToPath(uri) {
|
|
144
|
+
if (!uri) return null;
|
|
145
|
+
if (uri.startsWith('file://')) {
|
|
146
|
+
// file:///path/to/dir -> /path/to/dir
|
|
147
|
+
let filePath = uri.slice(7);
|
|
148
|
+
// Windows: file:///C:/path -> C:/path
|
|
149
|
+
if (filePath.match(/^\/[A-Za-z]:\//)) {
|
|
150
|
+
filePath = filePath.slice(1);
|
|
151
|
+
}
|
|
152
|
+
return decodeURIComponent(filePath);
|
|
153
|
+
}
|
|
154
|
+
// 如果不是 file:// URI,直接返回(可能已经是路径)
|
|
155
|
+
return uri;
|
|
156
|
+
}
|
|
157
|
+
|
|
114
158
|
/**
|
|
115
159
|
* 获取当前包版本
|
|
116
160
|
*/
|
|
@@ -268,6 +312,27 @@ async function startMcpServer() {
|
|
|
268
312
|
|
|
269
313
|
async function handleMessage(message) {
|
|
270
314
|
if (message.method === "initialize") {
|
|
315
|
+
// 从 initialize 请求中提取项目路径
|
|
316
|
+
const params = message.params || {};
|
|
317
|
+
|
|
318
|
+
// 尝试从 rootUri 或 workspaceFolders 获取项目路径
|
|
319
|
+
if (params.rootUri) {
|
|
320
|
+
mcpRootUri = uriToPath(params.rootUri);
|
|
321
|
+
log(`从 MCP initialize 获取项目路径: ${mcpRootUri}`);
|
|
322
|
+
} else if (params.workspaceFolders && params.workspaceFolders.length > 0) {
|
|
323
|
+
mcpRootUri = uriToPath(params.workspaceFolders[0].uri);
|
|
324
|
+
log(`从 MCP workspaceFolders 获取项目路径: ${mcpRootUri}`);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// 延迟同步 skills(在获取到项目路径后)
|
|
328
|
+
if (!skillsSynced && mcpRootUri) {
|
|
329
|
+
const projectRoot = getProjectRoot();
|
|
330
|
+
const ideConfig = getIDEConfig();
|
|
331
|
+
log(`[延迟同步] 工作目录: ${projectRoot}, IDE: ${ideConfig.name}`);
|
|
332
|
+
syncSkills(projectRoot, ideConfig);
|
|
333
|
+
skillsSynced = true;
|
|
334
|
+
}
|
|
335
|
+
|
|
271
336
|
return {
|
|
272
337
|
protocolVersion: "2024-11-05",
|
|
273
338
|
serverInfo: { name: "bkui-knowledge-server", version: "1.0.0" },
|
|
@@ -362,21 +427,34 @@ async function startMcpServer() {
|
|
|
362
427
|
log('MCP stdio 服务已启动');
|
|
363
428
|
}
|
|
364
429
|
|
|
430
|
+
/**
|
|
431
|
+
* 检查是否有明确的项目路径(命令行参数或环境变量)
|
|
432
|
+
*/
|
|
433
|
+
function hasExplicitProjectPath() {
|
|
434
|
+
const pathArg = process.argv.slice(2).find(arg => !arg.startsWith('-'));
|
|
435
|
+
return !!(pathArg || process.env.BKUI_PROJECT_ROOT);
|
|
436
|
+
}
|
|
437
|
+
|
|
365
438
|
/**
|
|
366
439
|
* 主入口
|
|
367
440
|
*/
|
|
368
441
|
async function main() {
|
|
369
|
-
const projectRoot = getProjectRoot();
|
|
370
442
|
const ideConfig = getIDEConfig();
|
|
371
443
|
|
|
372
|
-
//
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
444
|
+
// 如果有明确的项目路径(命令行参数或环境变量),立即同步
|
|
445
|
+
// 否则等待 MCP initialize 请求获取项目路径
|
|
446
|
+
if (hasExplicitProjectPath()) {
|
|
447
|
+
const projectRoot = getProjectRoot();
|
|
448
|
+
log(`工作目录: ${projectRoot}`);
|
|
449
|
+
log(`目标 IDE: ${ideConfig.name}`);
|
|
450
|
+
syncSkills(projectRoot, ideConfig);
|
|
451
|
+
skillsSynced = true;
|
|
452
|
+
} else {
|
|
453
|
+
log(`等待 MCP initialize 请求获取项目路径...`);
|
|
454
|
+
log(`目标 IDE: ${ideConfig.name}`);
|
|
455
|
+
}
|
|
378
456
|
|
|
379
|
-
//
|
|
457
|
+
// 启动 MCP 服务
|
|
380
458
|
await startMcpServer();
|
|
381
459
|
}
|
|
382
460
|
|