@ppdocs/mcp 2.8.0 → 2.8.1
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 +78 -11
- package/package.json +1 -1
package/dist/tools/index.js
CHANGED
|
@@ -23,14 +23,31 @@ 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.
|
|
45
|
+
// 3. 更新文档 (支持批量)
|
|
46
|
+
server.tool('kg_update_node', '更新文档内容(支持批量)', {
|
|
47
|
+
nodeId: z.union([
|
|
48
|
+
z.string(),
|
|
49
|
+
z.array(z.string())
|
|
50
|
+
]).describe('文档路径或路径数组'),
|
|
34
51
|
summary: z.string().optional().describe('一句话简介'),
|
|
35
52
|
content: z.string().optional().describe('Markdown内容'),
|
|
36
53
|
versions: z.array(z.object({
|
|
@@ -42,16 +59,66 @@ export function registerTools(server, projectId, _user) {
|
|
|
42
59
|
date: z.string(),
|
|
43
60
|
issue: z.string(),
|
|
44
61
|
solution: z.string()
|
|
45
|
-
})).optional().describe('修复记录')
|
|
62
|
+
})).optional().describe('修复记录'),
|
|
63
|
+
updates: z.array(z.object({
|
|
64
|
+
nodeId: z.string().describe('文档路径'),
|
|
65
|
+
summary: z.string().optional(),
|
|
66
|
+
content: z.string().optional(),
|
|
67
|
+
versions: z.array(z.object({
|
|
68
|
+
version: z.number(),
|
|
69
|
+
date: z.string(),
|
|
70
|
+
changes: z.string()
|
|
71
|
+
})).optional(),
|
|
72
|
+
bugfixes: z.array(z.object({
|
|
73
|
+
date: z.string(),
|
|
74
|
+
issue: z.string(),
|
|
75
|
+
solution: z.string()
|
|
76
|
+
})).optional()
|
|
77
|
+
})).optional().describe('批量更新数组(每项独立配置)')
|
|
46
78
|
}, async (args) => {
|
|
47
79
|
const decoded = decodeObjectStrings(args);
|
|
80
|
+
// 批量更新模式: 使用 updates 数组
|
|
81
|
+
if (decoded.updates && Array.isArray(decoded.updates)) {
|
|
82
|
+
const results = [];
|
|
83
|
+
for (const item of decoded.updates) {
|
|
84
|
+
if (item.nodeId === '/' || item.nodeId === '_root') {
|
|
85
|
+
results.push({ path: item.nodeId, success: false });
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const existing = await storage.getDoc(projectId, item.nodeId);
|
|
89
|
+
if (!existing) {
|
|
90
|
+
results.push({ path: item.nodeId, success: false });
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const updates = {};
|
|
94
|
+
if (item.summary !== undefined)
|
|
95
|
+
updates.summary = item.summary;
|
|
96
|
+
if (item.content !== undefined)
|
|
97
|
+
updates.content = item.content;
|
|
98
|
+
if (item.versions !== undefined)
|
|
99
|
+
updates.versions = item.versions;
|
|
100
|
+
if (item.bugfixes !== undefined)
|
|
101
|
+
updates.bugfixes = item.bugfixes;
|
|
102
|
+
const doc = await storage.updateDoc(projectId, item.nodeId, updates);
|
|
103
|
+
results.push({ path: item.nodeId, success: !!doc });
|
|
104
|
+
}
|
|
105
|
+
const successCount = results.filter(r => r.success).length;
|
|
106
|
+
const failedPaths = results.filter(r => !r.success).map(r => r.path);
|
|
107
|
+
let msg = `✅ 批量更新完成: ${successCount}/${decoded.updates.length} 成功`;
|
|
108
|
+
if (failedPaths.length > 0) {
|
|
109
|
+
msg += `\n❌ 失败: ${failedPaths.join(', ')}`;
|
|
110
|
+
}
|
|
111
|
+
return wrap(msg);
|
|
112
|
+
}
|
|
113
|
+
// 单个更新模式
|
|
48
114
|
const { nodeId, summary, content, versions, bugfixes } = decoded;
|
|
115
|
+
const singleNodeId = Array.isArray(nodeId) ? nodeId[0] : nodeId;
|
|
49
116
|
// 根文档必须使用 kg_update_root 更新
|
|
50
|
-
if (
|
|
117
|
+
if (singleNodeId === '/' || singleNodeId === '_root') {
|
|
51
118
|
return wrap('❌ 根文档请使用 kg_update_root 方法更新');
|
|
52
119
|
}
|
|
53
120
|
// 获取现有文档
|
|
54
|
-
const existing = await storage.getDoc(projectId,
|
|
121
|
+
const existing = await storage.getDoc(projectId, singleNodeId);
|
|
55
122
|
if (!existing) {
|
|
56
123
|
return wrap('更新失败(文档不存在)');
|
|
57
124
|
}
|
|
@@ -65,7 +132,7 @@ export function registerTools(server, projectId, _user) {
|
|
|
65
132
|
updates.versions = versions;
|
|
66
133
|
if (bugfixes !== undefined)
|
|
67
134
|
updates.bugfixes = bugfixes;
|
|
68
|
-
const doc = await storage.updateDoc(projectId,
|
|
135
|
+
const doc = await storage.updateDoc(projectId, singleNodeId, updates);
|
|
69
136
|
return wrap(doc ? JSON.stringify(doc, null, 2) : '更新失败');
|
|
70
137
|
});
|
|
71
138
|
// 3.5 更新根文档 (项目介绍)
|