@ppdocs/mcp 2.8.0 → 2.8.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.
- package/dist/tools/index.js +77 -11
- package/package.json +1 -1
package/dist/tools/index.js
CHANGED
|
@@ -23,29 +23,95 @@ export function registerTools(server, projectId, _user) {
|
|
|
23
23
|
});
|
|
24
24
|
return wrap(`✅ 文档已创建: ${decoded.path}\n\n${JSON.stringify(doc, null, 2)}`);
|
|
25
25
|
});
|
|
26
|
-
// 2. 删除文档
|
|
27
|
-
server.tool('kg_delete_node', '删除文档(
|
|
28
|
-
const
|
|
29
|
-
|
|
26
|
+
// 2. 删除文档 (支持批量)
|
|
27
|
+
server.tool('kg_delete_node', '删除文档(支持批量,根文档不可删除)', { nodeId: z.union([z.string(), z.array(z.string())]).describe('文档路径或路径数组') }, async (args) => {
|
|
28
|
+
const paths = Array.isArray(args.nodeId) ? args.nodeId : [args.nodeId];
|
|
29
|
+
const results = [];
|
|
30
|
+
for (const path of paths) {
|
|
31
|
+
const success = await storage.deleteDoc(projectId, path);
|
|
32
|
+
results.push({ path, success });
|
|
33
|
+
}
|
|
34
|
+
const successCount = results.filter(r => r.success).length;
|
|
35
|
+
const failedPaths = results.filter(r => !r.success).map(r => r.path);
|
|
36
|
+
if (paths.length === 1) {
|
|
37
|
+
return wrap(results[0].success ? '删除成功' : '删除失败(文档不存在或是根文档)');
|
|
38
|
+
}
|
|
39
|
+
let msg = `✅ 批量删除完成: ${successCount}/${paths.length} 成功`;
|
|
40
|
+
if (failedPaths.length > 0) {
|
|
41
|
+
msg += `\n❌ 失败: ${failedPaths.join(', ')}`;
|
|
42
|
+
}
|
|
43
|
+
return wrap(msg);
|
|
30
44
|
});
|
|
31
|
-
// 3. 更新文档
|
|
32
|
-
server.tool('kg_update_node', '
|
|
33
|
-
nodeId: z.string().describe('
|
|
34
|
-
summary: z.string().optional().describe('
|
|
35
|
-
content: z.string().optional().describe('Markdown内容'),
|
|
45
|
+
// 3. 更新文档 (支持单个/批量两种模式)
|
|
46
|
+
server.tool('kg_update_node', '更新文档内容。【单个模式】nodeId+字段;【批量模式】仅传updates数组。两种模式二选一', {
|
|
47
|
+
nodeId: z.string().optional().describe('【单个模式】文档路径,如"/前端/组件/Button"'),
|
|
48
|
+
summary: z.string().optional().describe('【单个模式】一句话简介'),
|
|
49
|
+
content: z.string().optional().describe('【单个模式】Markdown内容'),
|
|
36
50
|
versions: z.array(z.object({
|
|
37
51
|
version: z.number(),
|
|
38
52
|
date: z.string(),
|
|
39
53
|
changes: z.string()
|
|
40
|
-
})).optional().describe('
|
|
54
|
+
})).optional().describe('【单个模式】版本记录数组'),
|
|
41
55
|
bugfixes: z.array(z.object({
|
|
42
56
|
date: z.string(),
|
|
43
57
|
issue: z.string(),
|
|
44
58
|
solution: z.string()
|
|
45
|
-
})).optional().describe('
|
|
59
|
+
})).optional().describe('【单个模式】修复记录数组'),
|
|
60
|
+
updates: z.array(z.object({
|
|
61
|
+
nodeId: z.string().describe('文档路径'),
|
|
62
|
+
summary: z.string().optional(),
|
|
63
|
+
content: z.string().optional(),
|
|
64
|
+
versions: z.array(z.object({
|
|
65
|
+
version: z.number(),
|
|
66
|
+
date: z.string(),
|
|
67
|
+
changes: z.string()
|
|
68
|
+
})).optional(),
|
|
69
|
+
bugfixes: z.array(z.object({
|
|
70
|
+
date: z.string(),
|
|
71
|
+
issue: z.string(),
|
|
72
|
+
solution: z.string()
|
|
73
|
+
})).optional()
|
|
74
|
+
})).optional().describe('【批量模式】更新数组,每项包含nodeId和要更新的字段')
|
|
46
75
|
}, async (args) => {
|
|
47
76
|
const decoded = decodeObjectStrings(args);
|
|
77
|
+
// 批量更新模式: 使用 updates 数组
|
|
78
|
+
if (decoded.updates && Array.isArray(decoded.updates)) {
|
|
79
|
+
const results = [];
|
|
80
|
+
for (const item of decoded.updates) {
|
|
81
|
+
if (item.nodeId === '/' || item.nodeId === '_root') {
|
|
82
|
+
results.push({ path: item.nodeId, success: false });
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const existing = await storage.getDoc(projectId, item.nodeId);
|
|
86
|
+
if (!existing) {
|
|
87
|
+
results.push({ path: item.nodeId, success: false });
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const updates = {};
|
|
91
|
+
if (item.summary !== undefined)
|
|
92
|
+
updates.summary = item.summary;
|
|
93
|
+
if (item.content !== undefined)
|
|
94
|
+
updates.content = item.content;
|
|
95
|
+
if (item.versions !== undefined)
|
|
96
|
+
updates.versions = item.versions;
|
|
97
|
+
if (item.bugfixes !== undefined)
|
|
98
|
+
updates.bugfixes = item.bugfixes;
|
|
99
|
+
const doc = await storage.updateDoc(projectId, item.nodeId, updates);
|
|
100
|
+
results.push({ path: item.nodeId, success: !!doc });
|
|
101
|
+
}
|
|
102
|
+
const successCount = results.filter(r => r.success).length;
|
|
103
|
+
const failedPaths = results.filter(r => !r.success).map(r => r.path);
|
|
104
|
+
let msg = `✅ 批量更新完成: ${successCount}/${decoded.updates.length} 成功`;
|
|
105
|
+
if (failedPaths.length > 0) {
|
|
106
|
+
msg += `\n❌ 失败: ${failedPaths.join(', ')}`;
|
|
107
|
+
}
|
|
108
|
+
return wrap(msg);
|
|
109
|
+
}
|
|
110
|
+
// 单个更新模式: 必须提供 nodeId
|
|
48
111
|
const { nodeId, summary, content, versions, bugfixes } = decoded;
|
|
112
|
+
if (!nodeId) {
|
|
113
|
+
return wrap('❌ 请提供 nodeId(单个模式)或 updates 数组(批量模式)');
|
|
114
|
+
}
|
|
49
115
|
// 根文档必须使用 kg_update_root 更新
|
|
50
116
|
if (nodeId === '/' || nodeId === '_root') {
|
|
51
117
|
return wrap('❌ 根文档请使用 kg_update_root 方法更新');
|