@ppdocs/mcp 2.6.23 → 2.6.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.
- package/dist/storage/types.d.ts +2 -0
- package/dist/tools/index.js +20 -5
- package/package.json +1 -1
- package/templates/commands/pp/sync.md +75 -9
package/dist/storage/types.d.ts
CHANGED
|
@@ -51,9 +51,11 @@ export interface NodeData {
|
|
|
51
51
|
testRules?: string[];
|
|
52
52
|
reviewRules?: string[];
|
|
53
53
|
codeStyle?: string[];
|
|
54
|
+
unitTests?: string[];
|
|
54
55
|
createdAt?: string;
|
|
55
56
|
updatedAt?: string;
|
|
56
57
|
lastAccessedAt?: string;
|
|
58
|
+
lastSyncAt?: string;
|
|
57
59
|
versions?: VersionRecord[];
|
|
58
60
|
bugfixes?: BugfixRecord[];
|
|
59
61
|
}
|
package/dist/tools/index.js
CHANGED
|
@@ -64,17 +64,18 @@ export function registerTools(server, projectId, _user) {
|
|
|
64
64
|
version: z.number(),
|
|
65
65
|
date: z.string(),
|
|
66
66
|
changes: z.string()
|
|
67
|
-
})).optional().describe('版本记录'),
|
|
67
|
+
})).optional().describe('版本记录(0.1起始,AI控制递增)'),
|
|
68
68
|
bugfixes: z.array(z.object({
|
|
69
69
|
id: z.string(),
|
|
70
70
|
date: z.string(),
|
|
71
71
|
issue: z.string(),
|
|
72
72
|
solution: z.string(),
|
|
73
73
|
impact: z.string().optional()
|
|
74
|
-
})).optional().describe('修复记录')
|
|
74
|
+
})).optional().describe('修复记录'),
|
|
75
|
+
lastSyncAt: z.string().optional().describe('代码↔图谱最后同步时间(ISO时间戳)')
|
|
75
76
|
}, async (args) => {
|
|
76
77
|
const decoded = decodeObjectStrings(args);
|
|
77
|
-
const { nodeId, tags, relatedFiles, versions, bugfixes, path, ...rest } = decoded;
|
|
78
|
+
const { nodeId, tags, relatedFiles, versions, bugfixes, path, lastSyncAt, ...rest } = decoded;
|
|
78
79
|
// 根节点必须使用 kg_update_root 更新
|
|
79
80
|
if (nodeId === 'root') {
|
|
80
81
|
return wrap(projectId, '❌ 根节点请使用 kg_update_root 方法更新');
|
|
@@ -91,6 +92,8 @@ export function registerTools(server, projectId, _user) {
|
|
|
91
92
|
updates.bugfixes = bugfixes;
|
|
92
93
|
if (path !== undefined)
|
|
93
94
|
updates.path = path;
|
|
95
|
+
if (lastSyncAt !== undefined)
|
|
96
|
+
updates.lastSyncAt = lastSyncAt;
|
|
94
97
|
const node = await storage.updateNode(projectId, nodeId, updates);
|
|
95
98
|
return wrap(projectId, node ? JSON.stringify(node, null, 2) : '更新失败(节点不存在或已锁定)');
|
|
96
99
|
});
|
|
@@ -142,8 +145,8 @@ export function registerTools(server, projectId, _user) {
|
|
|
142
145
|
return wrap(projectId, node ? JSON.stringify(node, null, 2) : '操作失败');
|
|
143
146
|
});
|
|
144
147
|
// 5. 搜索节点
|
|
145
|
-
server.tool('kg_search', '
|
|
146
|
-
keywords: z.array(z.string()).describe('关键词列表(OR逻辑)'),
|
|
148
|
+
server.tool('kg_search', '关键词搜索节点,按命中率排序返回。空白关键词[""]返回全部节点', {
|
|
149
|
+
keywords: z.array(z.string()).describe('关键词列表(OR逻辑),空白[""]返回全部'),
|
|
147
150
|
limit: z.number().optional().describe('返回数量(默认10)')
|
|
148
151
|
}, async (args) => {
|
|
149
152
|
const results = await storage.searchNodes(projectId, args.keywords, args.limit || 10);
|
|
@@ -158,6 +161,18 @@ export function registerTools(server, projectId, _user) {
|
|
|
158
161
|
const json = JSON.stringify(output, null, 2);
|
|
159
162
|
return wrap(projectId, `${json}\n\n💡 需要详细内容请使用 kg_read_node(nodeId) 获取节点详情`);
|
|
160
163
|
});
|
|
164
|
+
// 5.5 列出所有标签
|
|
165
|
+
server.tool('kg_list_tags', '获取所有节点使用过的标签列表(去重)', {}, async () => {
|
|
166
|
+
const nodes = await storage.listNodes(projectId);
|
|
167
|
+
const tagSet = new Set();
|
|
168
|
+
for (const node of nodes) {
|
|
169
|
+
if (node.categories && Array.isArray(node.categories)) {
|
|
170
|
+
node.categories.forEach(cat => tagSet.add(cat));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const tags = Array.from(tagSet).sort();
|
|
174
|
+
return wrap(projectId, JSON.stringify({ total: tags.length, tags }, null, 2));
|
|
175
|
+
});
|
|
161
176
|
// 6. 路径查找
|
|
162
177
|
server.tool('kg_find_path', '查找两节点间的依赖路径', {
|
|
163
178
|
startId: z.string().describe('起点节点ID'),
|
package/package.json
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
| **代码即真理** | 代码与图谱冲突时以 Git 状态为准,强制覆写;禁止保留幽灵节点 |
|
|
7
7
|
| **拓扑优先** | Types → Utils → Services → UI,底层未建不创建上层 |
|
|
8
8
|
| **引用强约束** | relatedFiles 精确锚定物理路径;signature 为代码唯一标识符 |
|
|
9
|
-
| **版本追踪** |
|
|
9
|
+
| **版本追踪** | 版本号以 0.1 起始,每次同步有变动必须更新版本号 (AI控制递增) |
|
|
10
|
+
| **版本一致性** | 同步完成后更新 lastSyncAt,用于检测代码↔图谱是否同步 |
|
|
11
|
+
| **标签完整性** | 每节点 ≥3 个分类标签,标签由AI管理 |
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
@@ -19,19 +21,32 @@
|
|
|
19
21
|
|
|
20
22
|
---
|
|
21
23
|
|
|
22
|
-
## 标准流程
|
|
24
|
+
## 标准流程 (5步)
|
|
23
25
|
|
|
24
|
-
### Step 1:
|
|
26
|
+
### Step 1: 变更检测
|
|
25
27
|
```
|
|
26
28
|
task_create({ title:"KG同步", goals:["检测变更","更新节点","验证覆盖"], related_nodes:["root"] })
|
|
27
29
|
|
|
28
30
|
recent模式: git diff --name-only HEAD~3
|
|
29
31
|
all模式: Glob src/**/*.{ts,tsx}
|
|
32
|
+
|
|
33
|
+
⭐ kg_search([""]) 一次获取全部现有节点 (替代逐个search)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**版本一致性检测** ⭐新增:
|
|
30
37
|
```
|
|
38
|
+
对每个有 relatedFiles 的节点:
|
|
39
|
+
1. 获取文件 mtime (通过 Bash stat 或 fs.statSync)
|
|
40
|
+
2. 对比节点的 lastSyncAt
|
|
41
|
+
3. mtime > lastSyncAt → 标记为 [OUTDATED] 需同步
|
|
42
|
+
4. lastSyncAt 不存在 → 标记为 [UNTRACKED] 从未同步
|
|
43
|
+
```
|
|
44
|
+
|
|
31
45
|
**输出变更清单**:
|
|
32
46
|
```
|
|
33
47
|
├─ 🟢 [NEW] src/services/Payment.ts (待创建)
|
|
34
48
|
├─ 🟡 [MOD] src/utils/format.ts (待更新)
|
|
49
|
+
├─ 🟠 [OUTDATED] src/hooks/useAuth.ts (代码已改,图谱未同步)
|
|
35
50
|
└─ 🔴 [DEL] src/legacy/old.ts (待废弃)
|
|
36
51
|
```
|
|
37
52
|
等待用户确认 `OK`
|
|
@@ -39,13 +54,21 @@ all模式: Glob src/**/*.{ts,tsx}
|
|
|
39
54
|
### Step 2: 依赖解析 + 拓扑排序
|
|
40
55
|
解析 import 语句 → 构建依赖树 → 拓扑排序确保底层先处理
|
|
41
56
|
|
|
57
|
+
### Step 2.5: 标签完整性预检 ⭐新增
|
|
58
|
+
```
|
|
59
|
+
kg_list_tags() → 获取现有标签词库 (91个标签)
|
|
60
|
+
检查待处理节点:
|
|
61
|
+
- 标签 < 3 → 自动补全建议
|
|
62
|
+
- 使用现有标签词库保持一致性
|
|
63
|
+
```
|
|
64
|
+
|
|
42
65
|
### Step 3: 原子化执行
|
|
43
66
|
对每个文件:
|
|
44
67
|
```
|
|
45
68
|
1. 读取源码 → 提取 signature/imports/comments
|
|
46
|
-
2. kg_search
|
|
69
|
+
2. 从 Step1 缓存查找现有节点 (无需再次kg_search)
|
|
47
70
|
3. 执行写入:
|
|
48
|
-
- NEW: kg_create_node (全字段 + relatedFiles)
|
|
71
|
+
- NEW: kg_create_node (全字段 + relatedFiles + ⚠️tags≥3)
|
|
49
72
|
- MOD: kg_update_node (变动字段 + 追加 versions)
|
|
50
73
|
- DEL: kg_update_node(status:"deprecated") 或 kg_delete_node
|
|
51
74
|
4. 每5个文件: task_add_log(progress, "已处理 N/M")
|
|
@@ -58,20 +81,43 @@ all模式: Glob src/**/*.{ts,tsx}
|
|
|
58
81
|
kg_update_node({
|
|
59
82
|
nodeId: "xxx",
|
|
60
83
|
description: "新描述",
|
|
84
|
+
lastSyncAt: new Date().toISOString(), // ⭐ 更新同步时间戳
|
|
61
85
|
versions: [...现有versions, {
|
|
62
|
-
version:
|
|
86
|
+
version: 上一版本 + 0.1, // ⭐ 0.1起始,AI控制递增
|
|
63
87
|
date: "ISO时间",
|
|
64
88
|
changes: "本次变更摘要"
|
|
65
89
|
}]
|
|
66
90
|
})
|
|
67
91
|
```
|
|
68
92
|
|
|
69
|
-
|
|
93
|
+
**代码版本注释** (源码文件头部):
|
|
94
|
+
```typescript
|
|
95
|
+
// @version 0.1
|
|
96
|
+
// 或 JSDoc 格式
|
|
97
|
+
/**
|
|
98
|
+
* @version 0.1
|
|
99
|
+
*/
|
|
70
100
|
```
|
|
71
|
-
|
|
101
|
+
|
|
102
|
+
**同步时间戳规则** ⭐新增:
|
|
103
|
+
```
|
|
104
|
+
NEW: kg_create_node 后自动设置 lastSyncAt = now
|
|
105
|
+
MOD: kg_update_node 时必须传 lastSyncAt = now
|
|
106
|
+
OUTDATED: 仅更新 lastSyncAt (无需改 description/versions)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Step 4: 关系校验 ⭐优化
|
|
110
|
+
```
|
|
111
|
+
1. kg_read_node(nodeId, depth=1) 批量校验上下游关系
|
|
72
112
|
2. kg_list_nodes({maxEdges:0}) 检查孤立节点
|
|
73
113
|
3. 检查断链 (dependencies 指向不存在的 signature)
|
|
74
|
-
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Step 5: 交付报告 ⭐增强
|
|
117
|
+
```
|
|
118
|
+
1. 统计覆盖率
|
|
119
|
+
2. kg_list_tags() 输出标签分布
|
|
120
|
+
3. task_complete({
|
|
75
121
|
summary: "同步完成...",
|
|
76
122
|
difficulties: ["遇到的困难"],
|
|
77
123
|
solutions: ["采用的方案"],
|
|
@@ -87,19 +133,36 @@ kg_update_node({
|
|
|
87
133
|
| 更新节点 | 12 | ✅ |
|
|
88
134
|
| 废弃节点 | 1 | ⚠️ |
|
|
89
135
|
| 版本追加 | 8 | ✅ |
|
|
136
|
+
| 标签补全 | 5 | ✅ |
|
|
137
|
+
| 同步时间戳更新 | 15 | ✅ |
|
|
138
|
+
| 版本一致率 | 100% | 🟢 |
|
|
90
139
|
| 覆盖率 | 98.5% | 🟢 |
|
|
140
|
+
| 标签总数 | 91 | 📊 |
|
|
91
141
|
|
|
92
142
|
建议: git add . && git commit -m "chore: sync kg"
|
|
93
143
|
```
|
|
94
144
|
|
|
95
145
|
---
|
|
96
146
|
|
|
147
|
+
## MCP 工具速查 ⭐新增
|
|
148
|
+
|
|
149
|
+
| 工具 | 用途 | 示例 |
|
|
150
|
+
|:---|:---|:---|
|
|
151
|
+
| `kg_search([""])` | 获取全部节点 | 变更检测时一次拉取 |
|
|
152
|
+
| `kg_list_tags` | 标签词库 | 保持标签一致性 |
|
|
153
|
+
| `kg_read_node(id, depth=1)` | 含关系的详情 | 校验上下游 |
|
|
154
|
+
| `kg_list_nodes({maxEdges:0})` | 孤立节点 | 发现断链 |
|
|
155
|
+
| `kg_list_nodes` | 含summary列表 | 覆盖率报告 |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
97
159
|
## 异常处理
|
|
98
160
|
| 场景 | 反应 |
|
|
99
161
|
|:---|:---|
|
|
100
162
|
| git status 不干净 | 警告 + 询问是否强制继续 |
|
|
101
163
|
| kg_search 返回多个同名节点 | 暂停,列出候选请求人工绑定 |
|
|
102
164
|
| 文件解析失败 | task_add_log(issue) + 标记 Skipped,不中断队列 |
|
|
165
|
+
| 标签不足3个 | 自动从词库补全,记录日志 |
|
|
103
166
|
|
|
104
167
|
---
|
|
105
168
|
|
|
@@ -110,3 +173,6 @@ kg_update_node({
|
|
|
110
173
|
| 文件路径 | relatedFiles | 相对项目根 (如 `src/utils/auth.ts`) |
|
|
111
174
|
| export 函数/类 | signature | 标识符名 (如 `AuthService`) |
|
|
112
175
|
| JSDoc/Comments | description | 优先注释,无则代码生成摘要 |
|
|
176
|
+
| 功能分类 | tags | ≥3个,使用 kg_list_tags 词库 |
|
|
177
|
+
| 同步时间 | lastSyncAt | 每次同步完成时设为当前 ISO 时间戳 |
|
|
178
|
+
| `// @version 0.1` | versions[].version | 代码文件头注释,0.1起始 |
|