@ppdocs/mcp 3.2.23 → 3.2.25
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.
|
@@ -51,6 +51,8 @@ export declare class PpdocsApiClient {
|
|
|
51
51
|
updateFlowchartNode(chartId: string, nodeId: string, node: unknown, changeDesc?: string): Promise<unknown>;
|
|
52
52
|
/** 原子删除单个节点 (后端自动清理关联边) */
|
|
53
53
|
deleteFlowchartNode(chartId: string, nodeId: string): Promise<unknown>;
|
|
54
|
+
/** 删除流程图 (后端自动级联删子图+清父节点引用) */
|
|
55
|
+
deleteFlowchart(chartId: string): Promise<unknown>;
|
|
54
56
|
getFlowchartOrphans(): Promise<unknown[]>;
|
|
55
57
|
getFlowchartHealth(): Promise<unknown[]>;
|
|
56
58
|
/** 列出所有可访问的项目 */
|
|
@@ -372,6 +372,12 @@ export class PpdocsApiClient {
|
|
|
372
372
|
method: 'DELETE'
|
|
373
373
|
});
|
|
374
374
|
}
|
|
375
|
+
/** 删除流程图 (后端自动级联删子图+清父节点引用) */
|
|
376
|
+
async deleteFlowchart(chartId) {
|
|
377
|
+
return this.request(`/flowcharts/${chartId}`, {
|
|
378
|
+
method: 'DELETE'
|
|
379
|
+
});
|
|
380
|
+
}
|
|
375
381
|
async getFlowchartOrphans() {
|
|
376
382
|
return this.request('/flowcharts/orphans');
|
|
377
383
|
}
|
package/dist/tools/flowchart.js
CHANGED
|
@@ -24,8 +24,8 @@ const EdgeSchema = z.object({
|
|
|
24
24
|
});
|
|
25
25
|
export function registerFlowchartTools(server, ctx) {
|
|
26
26
|
const client = () => getClient();
|
|
27
|
-
server.tool('kg_flowchart', '🔀 逻辑流程图(关系型知识锚点) — action: list|get|get_node(★爆炸式上下文)|update_node|delete_node|batch_add|bind|unbind|orphans|health', {
|
|
28
|
-
action: z.enum(['list', 'get', 'get_node', 'update_node', 'delete_node', 'batch_add', 'bind', 'unbind', 'orphans', 'health'])
|
|
27
|
+
server.tool('kg_flowchart', '🔀 逻辑流程图(关系型知识锚点) — action: list|get|get_node(★爆炸式上下文)|update_node|delete_node|batch_add|bind|unbind|orphans|health|create_chart|delete_chart', {
|
|
28
|
+
action: z.enum(['list', 'get', 'get_node', 'update_node', 'delete_node', 'batch_add', 'bind', 'unbind', 'orphans', 'health', 'create_chart', 'delete_chart'])
|
|
29
29
|
.describe('操作类型'),
|
|
30
30
|
chartId: z.string().optional()
|
|
31
31
|
.describe('流程图ID (默认"main")'),
|
|
@@ -49,6 +49,10 @@ export function registerFlowchartTools(server, ctx) {
|
|
|
49
49
|
domain: z.string().optional().describe('update_node: 新领域'),
|
|
50
50
|
input: z.array(z.string()).optional().describe('update_node: 新输入 / bind的源代码文件'),
|
|
51
51
|
output: z.array(z.string()).optional().describe('update_node: 新输出'),
|
|
52
|
+
subFlowchart: z.string().optional().describe('update_node: 绑定子图ID / create_chart时自动设置'),
|
|
53
|
+
title: z.string().optional().describe('create_chart: 子图标题'),
|
|
54
|
+
parentChart: z.string().optional().describe('create_chart: 父图ID (默认main)'),
|
|
55
|
+
parentNode: z.string().optional().describe('create_chart: 挂载到父图的哪个节点ID'),
|
|
52
56
|
// bind/unbind
|
|
53
57
|
files: z.array(z.string()).optional()
|
|
54
58
|
.describe('源代码文件路径 (bind/unbind)'),
|
|
@@ -250,39 +254,46 @@ export function registerFlowchartTools(server, ctx) {
|
|
|
250
254
|
const chartId = decoded.chartId || 'main';
|
|
251
255
|
if (!decoded.nodeId)
|
|
252
256
|
return wrap('❌ update_node 需要 nodeId');
|
|
253
|
-
|
|
254
|
-
|
|
257
|
+
const chart = await client().getFlowchart(chartId);
|
|
258
|
+
if (!chart)
|
|
259
|
+
return wrap(`❌ 流程图 "${chartId}" 不存在`);
|
|
260
|
+
const node = (chart.nodes || []).find((n) => n.id === decoded.nodeId);
|
|
261
|
+
if (!node)
|
|
262
|
+
return wrap(`❌ 节点 "${decoded.nodeId}" 不存在`);
|
|
255
263
|
const changes = [];
|
|
256
264
|
if (decoded.label !== undefined) {
|
|
257
|
-
|
|
265
|
+
node.label = decoded.label;
|
|
258
266
|
changes.push('label');
|
|
259
267
|
}
|
|
260
268
|
if (decoded.description !== undefined) {
|
|
261
|
-
|
|
269
|
+
node.description = decoded.description;
|
|
262
270
|
changes.push('description');
|
|
263
271
|
}
|
|
264
272
|
if (decoded.nodeType !== undefined) {
|
|
265
|
-
|
|
273
|
+
node.nodeType = decoded.nodeType;
|
|
266
274
|
changes.push('nodeType');
|
|
267
275
|
}
|
|
268
276
|
if (decoded.domain !== undefined) {
|
|
269
|
-
|
|
277
|
+
node.domain = decoded.domain;
|
|
270
278
|
changes.push('domain');
|
|
271
279
|
}
|
|
272
280
|
if (decoded.input !== undefined) {
|
|
273
|
-
|
|
281
|
+
node.input = decoded.input;
|
|
274
282
|
changes.push('input');
|
|
275
283
|
}
|
|
276
284
|
if (decoded.output !== undefined) {
|
|
277
|
-
|
|
285
|
+
node.output = decoded.output;
|
|
278
286
|
changes.push('output');
|
|
279
287
|
}
|
|
288
|
+
if (decoded.subFlowchart !== undefined) {
|
|
289
|
+
node.subFlowchart = decoded.subFlowchart;
|
|
290
|
+
changes.push('subFlowchart');
|
|
291
|
+
}
|
|
280
292
|
if (changes.length === 0)
|
|
281
293
|
return wrap('ℹ️ 无变更 — 请提供要更新的字段');
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return wrap(`✅ 节点已更新: ${decoded.label || decoded.nodeId} [${chartId}/${decoded.nodeId}]\n更新字段: ${changes.join(', ')}`);
|
|
294
|
+
node.lastUpdated = new Date().toISOString();
|
|
295
|
+
await client().saveFlowchart(chartId, chart);
|
|
296
|
+
return wrap(`✅ 节点已更新: ${node.label} [${chartId}/${decoded.nodeId}]\n更新字段: ${changes.join(', ')}`);
|
|
286
297
|
}
|
|
287
298
|
case 'delete_node': {
|
|
288
299
|
const chartId = decoded.chartId || 'main';
|
|
@@ -311,7 +322,7 @@ export function registerFlowchartTools(server, ctx) {
|
|
|
311
322
|
boundFiles: [],
|
|
312
323
|
boundDirs: [],
|
|
313
324
|
boundTasks: [],
|
|
314
|
-
subFlowchart: null,
|
|
325
|
+
subFlowchart: n.subFlowchart || null,
|
|
315
326
|
position: null,
|
|
316
327
|
versions: [],
|
|
317
328
|
lastUpdated: '',
|
|
@@ -476,6 +487,70 @@ export function registerFlowchartTools(server, ctx) {
|
|
|
476
487
|
const icon = isBind ? '🔗' : '⛓️';
|
|
477
488
|
return wrap(`${icon} ${isBind ? '绑定' : '解绑'}完成 [${decoded.nodeId}]: ${changes.join(', ')}`);
|
|
478
489
|
}
|
|
490
|
+
case 'create_chart': {
|
|
491
|
+
const newChartId = decoded.chartId;
|
|
492
|
+
if (!newChartId)
|
|
493
|
+
return wrap('❌ create_chart 需要 chartId (子图ID)');
|
|
494
|
+
if (newChartId === 'main')
|
|
495
|
+
return wrap('❌ 不能创建 main,主图已存在');
|
|
496
|
+
// 检查是否已存在
|
|
497
|
+
const existing = await client().getFlowchart(newChartId);
|
|
498
|
+
if (existing)
|
|
499
|
+
return wrap(`❌ 流程图 "${newChartId}" 已存在`);
|
|
500
|
+
const pChart = decoded.parentChart || 'main';
|
|
501
|
+
const pNode = decoded.parentNode;
|
|
502
|
+
// 构建子图数据
|
|
503
|
+
const subChartData = {
|
|
504
|
+
id: newChartId,
|
|
505
|
+
title: decoded.title || newChartId,
|
|
506
|
+
parentNode: pNode || null,
|
|
507
|
+
parentChart: pChart,
|
|
508
|
+
nodes: [],
|
|
509
|
+
edges: [],
|
|
510
|
+
};
|
|
511
|
+
// 如果提供了 nodes/edges,填充进去
|
|
512
|
+
if (decoded.nodes && decoded.nodes.length > 0) {
|
|
513
|
+
subChartData.nodes = decoded.nodes.map((n) => ({
|
|
514
|
+
id: n.id, label: n.label,
|
|
515
|
+
nodeType: n.nodeType || 'process', domain: n.domain || 'system',
|
|
516
|
+
input: n.input || [], output: n.output || [],
|
|
517
|
+
description: n.description || '', affiliation: n.affiliation || 'root',
|
|
518
|
+
boundDocs: [], boundFiles: [], boundDirs: [], boundTasks: [],
|
|
519
|
+
subFlowchart: null, position: null, versions: [], lastUpdated: '', lastQueried: '',
|
|
520
|
+
}));
|
|
521
|
+
}
|
|
522
|
+
if (decoded.edges && decoded.edges.length > 0) {
|
|
523
|
+
subChartData.edges = decoded.edges.map(e => ({
|
|
524
|
+
from: e.from, to: e.to, label: e.label || null, edgeType: e.edgeType || 'call',
|
|
525
|
+
}));
|
|
526
|
+
}
|
|
527
|
+
// 保存子图
|
|
528
|
+
await client().saveFlowchart(newChartId, subChartData);
|
|
529
|
+
// 自动更新父节点的 subFlowchart 引用
|
|
530
|
+
if (pNode) {
|
|
531
|
+
const parentChart = await client().getFlowchart(pChart);
|
|
532
|
+
if (parentChart) {
|
|
533
|
+
const parentNodeObj = (parentChart.nodes || []).find((n) => n.id === pNode);
|
|
534
|
+
if (parentNodeObj) {
|
|
535
|
+
parentNodeObj.subFlowchart = newChartId;
|
|
536
|
+
parentNodeObj.lastUpdated = new Date().toISOString();
|
|
537
|
+
await client().saveFlowchart(pChart, parentChart);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
const nodeCount = subChartData.nodes.length;
|
|
542
|
+
return wrap(`✅ 子图已创建: ${decoded.title || newChartId} [${newChartId}]\n父图: ${pChart}${pNode ? ` → 节点: ${pNode}` : ''}\n初始: ${nodeCount}节点`);
|
|
543
|
+
}
|
|
544
|
+
case 'delete_chart': {
|
|
545
|
+
const chartId = decoded.chartId;
|
|
546
|
+
if (!chartId)
|
|
547
|
+
return wrap('❌ delete_chart 需要 chartId');
|
|
548
|
+
if (chartId === 'main')
|
|
549
|
+
return wrap('❌ 不能删除主图 main');
|
|
550
|
+
// 后端自动级联: 清父节点引用 + 删子图的子图
|
|
551
|
+
await client().deleteFlowchart(chartId);
|
|
552
|
+
return wrap(`✅ 流程图已删除 [${chartId}] (子图已级联清理)`);
|
|
553
|
+
}
|
|
479
554
|
default:
|
|
480
555
|
return wrap(`❌ 未知 action: ${decoded.action}`);
|
|
481
556
|
}
|