@ppdocs/mcp 2.6.8 → 2.6.10
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/README.md +5 -2
- package/dist/storage/httpClient.d.ts +7 -14
- package/dist/storage/httpClient.js +30 -10
- package/dist/tools/index.js +11 -12
- package/package.json +1 -1
- package/templates/commands/pp/init.md +119 -74
- package/templates/commands/pp/sync.md +104 -75
- package/templates/hooks/SystemPrompt.md +102 -46
package/README.md
CHANGED
|
@@ -109,10 +109,9 @@ npx @ppdocs/mcp init -p <projectId> -k <key> --codex
|
|
|
109
109
|
| `kg_update_node` | 更新节点内容 |
|
|
110
110
|
| `kg_delete_node` | 删除节点 |
|
|
111
111
|
| `kg_lock_node` | 锁定节点 (AI 只能锁定,解锁需前端手动) |
|
|
112
|
-
| `kg_list_nodes` |
|
|
112
|
+
| `kg_list_nodes` | 列出节点 (支持 status/edges 过滤,maxEdges=0 查孤立节点) |
|
|
113
113
|
| `kg_search` | 关键词搜索 |
|
|
114
114
|
| `kg_find_path` | 查找依赖路径 |
|
|
115
|
-
| `kg_find_orphans` | 查找孤立节点 |
|
|
116
115
|
| `kg_get_relations` | 获取节点关系 |
|
|
117
116
|
|
|
118
117
|
### 任务管理工具
|
|
@@ -175,6 +174,10 @@ npx @ppdocs/mcp init -p <projectId> -k <key> --codex
|
|
|
175
174
|
|
|
176
175
|
## 更新日志
|
|
177
176
|
|
|
177
|
+
### v2.6.9
|
|
178
|
+
- ✨ `kg_list_nodes` 支持 status/minEdges/maxEdges 过滤
|
|
179
|
+
- 🗑️ 移除 `kg_find_orphans` (用 `kg_list_nodes(maxEdges: 0)` 替代)
|
|
180
|
+
|
|
178
181
|
### v2.5.0
|
|
179
182
|
- ✨ 新增 CLI init 命令,自动安装工作流模板
|
|
180
183
|
- ✨ 支持 Codex 模式 (--codex)
|
|
@@ -5,11 +5,16 @@
|
|
|
5
5
|
* API URL 格式: http://localhost:20001/api/:projectId/:password/...
|
|
6
6
|
*/
|
|
7
7
|
import type { NodeData, SearchResult, PathResult, BugfixRecord, Task, TaskSummary, TaskLogType, TaskExperience } from './types.js';
|
|
8
|
+
export interface ListNodesFilter {
|
|
9
|
+
status?: 'incomplete' | 'complete' | 'fixing' | 'refactoring' | 'deprecated';
|
|
10
|
+
minEdges?: number;
|
|
11
|
+
maxEdges?: number;
|
|
12
|
+
}
|
|
8
13
|
export declare class PpdocsApiClient {
|
|
9
14
|
private baseUrl;
|
|
10
15
|
constructor(apiUrl: string);
|
|
11
16
|
private request;
|
|
12
|
-
listNodes(): Promise<NodeData[]>;
|
|
17
|
+
listNodes(filter?: ListNodesFilter): Promise<NodeData[]>;
|
|
13
18
|
getNode(nodeId: string): Promise<NodeData | null>;
|
|
14
19
|
createNode(node: Partial<NodeData>): Promise<NodeData>;
|
|
15
20
|
updateNode(nodeId: string, updates: Partial<NodeData>): Promise<NodeData | null>;
|
|
@@ -22,12 +27,6 @@ export declare class PpdocsApiClient {
|
|
|
22
27
|
lockNode(nodeId: string, locked: boolean): Promise<NodeData | null>;
|
|
23
28
|
searchNodes(keywords: string[], limit?: number): Promise<SearchResult[]>;
|
|
24
29
|
findPath(startId: string, endId: string): Promise<PathResult | null>;
|
|
25
|
-
findOrphans(): Promise<Array<{
|
|
26
|
-
id: string;
|
|
27
|
-
title: string;
|
|
28
|
-
type: string;
|
|
29
|
-
status: string;
|
|
30
|
-
}>>;
|
|
31
30
|
getRelations(nodeId: string): Promise<Array<{
|
|
32
31
|
nodeId: string;
|
|
33
32
|
title: string;
|
|
@@ -52,7 +51,7 @@ export declare class PpdocsApiClient {
|
|
|
52
51
|
completeTask(taskId: string, experience: TaskExperience): Promise<Task | null>;
|
|
53
52
|
}
|
|
54
53
|
export declare function initClient(apiUrl: string): void;
|
|
55
|
-
export declare function listNodes(_projectId: string): Promise<NodeData[]>;
|
|
54
|
+
export declare function listNodes(_projectId: string, filter?: ListNodesFilter): Promise<NodeData[]>;
|
|
56
55
|
export declare function getNode(_projectId: string, nodeId: string): Promise<NodeData | null>;
|
|
57
56
|
export declare function createNode(_projectId: string, node: Partial<NodeData>): Promise<NodeData>;
|
|
58
57
|
export declare function updateNode(_projectId: string, nodeId: string, updates: Partial<NodeData>): Promise<NodeData | null>;
|
|
@@ -65,12 +64,6 @@ export declare function deleteNode(_projectId: string, nodeId: string): Promise<
|
|
|
65
64
|
export declare function lockNode(_projectId: string, nodeId: string, locked: boolean): Promise<NodeData | null>;
|
|
66
65
|
export declare function searchNodes(_projectId: string, keywords: string[], limit?: number): Promise<SearchResult[]>;
|
|
67
66
|
export declare function findPath(_projectId: string, startId: string, endId: string): Promise<PathResult | null>;
|
|
68
|
-
export declare function findOrphans(_projectId: string): Promise<Array<{
|
|
69
|
-
id: string;
|
|
70
|
-
title: string;
|
|
71
|
-
type: string;
|
|
72
|
-
status: string;
|
|
73
|
-
}>>;
|
|
74
67
|
export declare function getRelations(_projectId: string, nodeId: string): Promise<Array<{
|
|
75
68
|
nodeId: string;
|
|
76
69
|
title: string;
|
|
@@ -99,8 +99,34 @@ export class PpdocsApiClient {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
// ============ 节点操作 ============
|
|
102
|
-
async listNodes() {
|
|
103
|
-
|
|
102
|
+
async listNodes(filter) {
|
|
103
|
+
const nodes = await this.request('/nodes');
|
|
104
|
+
if (!filter)
|
|
105
|
+
return nodes;
|
|
106
|
+
// 计算每个节点的连接数 (入边+出边)
|
|
107
|
+
const edgeCounts = new Map();
|
|
108
|
+
nodes.forEach(n => edgeCounts.set(n.id, 0));
|
|
109
|
+
nodes.forEach(n => {
|
|
110
|
+
(n.dependencies || []).forEach(dep => {
|
|
111
|
+
// 出边: 当前节点依赖别人
|
|
112
|
+
edgeCounts.set(n.id, (edgeCounts.get(n.id) || 0) + 1);
|
|
113
|
+
// 入边: 被依赖的节点 (按 signature 匹配)
|
|
114
|
+
const target = nodes.find(t => t.signature?.toLowerCase() === dep.name.toLowerCase());
|
|
115
|
+
if (target)
|
|
116
|
+
edgeCounts.set(target.id, (edgeCounts.get(target.id) || 0) + 1);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
// 过滤
|
|
120
|
+
return nodes.filter(n => {
|
|
121
|
+
if (filter.status && n.status !== filter.status)
|
|
122
|
+
return false;
|
|
123
|
+
const edges = edgeCounts.get(n.id) || 0;
|
|
124
|
+
if (filter.minEdges !== undefined && edges < filter.minEdges)
|
|
125
|
+
return false;
|
|
126
|
+
if (filter.maxEdges !== undefined && edges > filter.maxEdges)
|
|
127
|
+
return false;
|
|
128
|
+
return true;
|
|
129
|
+
});
|
|
104
130
|
}
|
|
105
131
|
async getNode(nodeId) {
|
|
106
132
|
try {
|
|
@@ -228,9 +254,6 @@ export class PpdocsApiClient {
|
|
|
228
254
|
return null;
|
|
229
255
|
}
|
|
230
256
|
}
|
|
231
|
-
async findOrphans() {
|
|
232
|
-
return this.request('/orphans');
|
|
233
|
-
}
|
|
234
257
|
async getRelations(nodeId) {
|
|
235
258
|
const result = await this.request(`/relations/${nodeId}`);
|
|
236
259
|
// 转换字段名 (API 返回 type,前端期望 edgeType)
|
|
@@ -323,8 +346,8 @@ function getClient() {
|
|
|
323
346
|
return client;
|
|
324
347
|
}
|
|
325
348
|
// 导出与 fileStorage 相同的函数签名
|
|
326
|
-
export async function listNodes(_projectId) {
|
|
327
|
-
return getClient().listNodes();
|
|
349
|
+
export async function listNodes(_projectId, filter) {
|
|
350
|
+
return getClient().listNodes(filter);
|
|
328
351
|
}
|
|
329
352
|
export async function getNode(_projectId, nodeId) {
|
|
330
353
|
return getClient().getNode(nodeId);
|
|
@@ -350,9 +373,6 @@ export async function searchNodes(_projectId, keywords, limit) {
|
|
|
350
373
|
export async function findPath(_projectId, startId, endId) {
|
|
351
374
|
return getClient().findPath(startId, endId);
|
|
352
375
|
}
|
|
353
|
-
export async function findOrphans(_projectId) {
|
|
354
|
-
return getClient().findOrphans();
|
|
355
|
-
}
|
|
356
376
|
export async function getRelations(_projectId, nodeId) {
|
|
357
377
|
return getClient().getRelations(nodeId);
|
|
358
378
|
}
|
package/dist/tools/index.js
CHANGED
|
@@ -120,21 +120,20 @@ export function registerTools(server, projectId, _user) {
|
|
|
120
120
|
};
|
|
121
121
|
return wrap(projectId, JSON.stringify(output, null, 2));
|
|
122
122
|
});
|
|
123
|
-
// 7.
|
|
124
|
-
server.tool('kg_list_nodes', '
|
|
125
|
-
|
|
123
|
+
// 7. 列出节点 (支持过滤)
|
|
124
|
+
server.tool('kg_list_nodes', '列出节点,支持按状态/连接数过滤。maxEdges=0 可查孤立节点', {
|
|
125
|
+
status: z.enum(['incomplete', 'complete', 'fixing', 'refactoring', 'deprecated']).optional().describe('状态过滤'),
|
|
126
|
+
minEdges: z.number().optional().describe('最小连接数(含)'),
|
|
127
|
+
maxEdges: z.number().optional().describe('最大连接数(含),0=孤立节点')
|
|
128
|
+
}, async (args) => {
|
|
129
|
+
const filter = (args.status || args.minEdges !== undefined || args.maxEdges !== undefined)
|
|
130
|
+
? { status: args.status, minEdges: args.minEdges, maxEdges: args.maxEdges }
|
|
131
|
+
: undefined;
|
|
132
|
+
const nodes = await storage.listNodes(projectId, filter);
|
|
126
133
|
const output = nodes.map(n => ({ id: n.id, title: n.title, type: n.type, status: n.status, locked: n.locked }));
|
|
127
134
|
return wrap(projectId, JSON.stringify(output, null, 2));
|
|
128
135
|
});
|
|
129
|
-
// 8.
|
|
130
|
-
server.tool('kg_find_orphans', '查找无连线的孤立节点(用于清理)', {}, async () => {
|
|
131
|
-
const orphans = await storage.findOrphans(projectId);
|
|
132
|
-
if (orphans.length === 0) {
|
|
133
|
-
return wrap(projectId, '没有孤立节点');
|
|
134
|
-
}
|
|
135
|
-
return wrap(projectId, JSON.stringify(orphans, null, 2));
|
|
136
|
-
});
|
|
137
|
-
// 9. 查询节点关系网 (支持多层)
|
|
136
|
+
// 8. 查询节点关系网 (支持多层)
|
|
138
137
|
server.tool('kg_get_relations', '获取节点的上下游关系(谁依赖它/它依赖谁),支持多层查询', {
|
|
139
138
|
nodeId: z.string().describe('节点ID'),
|
|
140
139
|
depth: z.number().min(1).max(3).optional().describe('查询层数(默认1,最大3)')
|
package/package.json
CHANGED
|
@@ -4,103 +4,148 @@ description: 初始化知识图谱:100%扫描代码库,为每个模块创建
|
|
|
4
4
|
|
|
5
5
|
# /init 项目初始化
|
|
6
6
|
|
|
7
|
-
执行 `task_create("
|
|
7
|
+
执行 `task_create("项目初始化")` → 分阶段扫描 → 逐文件创建节点 → 完成后 `task_complete`
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Phase 1: 项目探测
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**技术栈识别**: package.json→Node/React | Cargo.toml→Rust | go.mod→Go | requirements.txt→Python
|
|
12
|
+
**架构分析**: 读取入口配置 → Glob扫描源码目录 → 按目录聚类 → 输出架构树
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
```
|
|
15
|
+
┌─ 推断架构 ────────────────────┐
|
|
16
|
+
│ [intro] 项目根: {名称} │
|
|
17
|
+
│ ├─ [intro] {模块A}: {路径} │
|
|
18
|
+
│ ├─ [logic] {模块B}: {路径} │
|
|
19
|
+
│ └─ [data] 共享类型 │
|
|
20
|
+
└───────────────────────────────┘
|
|
21
|
+
回复 OK 继续
|
|
22
|
+
```
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
**忽略**: node_modules, dist, build, .git, .next, target, __pycache__, .env*, *.lock, *.log, *.min.js
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
## Phase 2: 签名规则表
|
|
22
27
|
|
|
23
|
-
|
|
|
28
|
+
| 识别模式 | type | signature | categories |
|
|
29
|
+
|:---|:---|:---|:---|
|
|
30
|
+
| pages/views/routes | logic | `Page:{名称}` | `[ui, page]` |
|
|
31
|
+
| components | logic | `Comp:{名称}` | `[ui, component]` |
|
|
32
|
+
| use*.ts (Hook) | logic | `{名称}()` | `[hook]` |
|
|
33
|
+
| services/api | logic | `Svc:{名称}` | `[service, api]` |
|
|
34
|
+
| store/storage | logic | `Store:{名称}` | `[storage]` |
|
|
35
|
+
| utils/helpers | logic | `{函数名}()` | `[util, reusable]` |
|
|
36
|
+
| types/interfaces | data | `Type:{名称}` | `[type]` |
|
|
37
|
+
| config/*.json | intro | `Config:{名称}` | `[config]` |
|
|
38
|
+
| *.rs (Rust) | logic | `{mod}::{fn}` | `[rust]` |
|
|
39
|
+
| *.go (Go) | logic | `{pkg}.{Func}` | `[go]` |
|
|
40
|
+
|
|
41
|
+
### categories 分类 (17种)
|
|
42
|
+
`ui` `function` `class` `library` `reusable` `snippet` `data` `logic` `api` `config` `util` `service` `model` `constant` `type` `hook` `middleware`
|
|
43
|
+
|
|
44
|
+
## Phase 3: 字段规范 (MUST 全部填写)
|
|
45
|
+
|
|
46
|
+
| 字段 | 规则 | 示例 |
|
|
24
47
|
|:---|:---|:---|
|
|
25
|
-
| title |
|
|
26
|
-
| type |
|
|
27
|
-
| status |
|
|
28
|
-
| signature |
|
|
29
|
-
| categories |
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```markdown
|
|
40
|
-
```mermaid
|
|
41
|
-
flowchart LR
|
|
42
|
-
A[入口/触发] --> B{条件判断}
|
|
43
|
-
B -->|成功| C[核心处理]
|
|
44
|
-
B -->|失败| D[错误处理]
|
|
45
|
-
C --> E[返回结果]
|
|
48
|
+
| title | 中文描述 | `用户认证服务` |
|
|
49
|
+
| type | logic/data/intro | `logic` |
|
|
50
|
+
| status | 统一 `incomplete` | 待确认后改 complete |
|
|
51
|
+
| signature | 按上方规则生成 | `useAuth()` |
|
|
52
|
+
| categories | 分类数组 | `["hook", "auth"]` |
|
|
53
|
+
| **relatedFiles** | **MUST: 源文件路径** | `["src/hooks/useAuth.ts"]` |
|
|
54
|
+
| **dependencies** | **MUST: 解析 import** | `[{name: "xxx", description: "用途"}]` |
|
|
55
|
+
| description | 见下方模板 | |
|
|
56
|
+
|
|
57
|
+
### relatedFiles 提取规则 (MUST)
|
|
58
|
+
```
|
|
59
|
+
1. 当前文件路径 → relatedFiles[0]
|
|
60
|
+
2. 该文件 import 的本地文件 → relatedFiles[1..n]
|
|
61
|
+
3. NEVER 留空,至少包含当前文件
|
|
46
62
|
```
|
|
47
63
|
|
|
48
|
-
|
|
49
|
-
|:---|:---|:---|
|
|
50
|
-
| Input | `ParamType` | 参数描述 |
|
|
51
|
-
| Output | `ReturnType` | 返回值描述 |
|
|
52
|
-
|
|
53
|
-
**核心逻辑**: 一句话描述函数职责
|
|
64
|
+
### dependencies 推断规则 (MUST)
|
|
54
65
|
```
|
|
66
|
+
依赖 = "谁调用了谁"
|
|
67
|
+
|
|
68
|
+
处理每个文件时:
|
|
69
|
+
1. 解析 import/require 语句 → 提取本地模块
|
|
70
|
+
2. 对每个 import:
|
|
71
|
+
│
|
|
72
|
+
├─ 匹配方式1: 签名匹配
|
|
73
|
+
│ import { useAuth } → 匹配 signature="useAuth()"
|
|
74
|
+
│
|
|
75
|
+
├─ 匹配方式2: 路径匹配
|
|
76
|
+
│ 遍历已创建节点的 relatedFiles
|
|
77
|
+
│ 若 import 路径 ∈ 某节点的 relatedFiles → 匹配
|
|
78
|
+
│
|
|
79
|
+
└─ 匹配成功 → dependencies.push({
|
|
80
|
+
name: 目标节点的 signature,
|
|
81
|
+
description: "用途"
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### description 模板
|
|
55
86
|
|
|
56
|
-
|
|
87
|
+
**logic 节点**:
|
|
57
88
|
```markdown
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class TypeName {
|
|
61
|
-
+fieldType field1
|
|
62
|
-
+fieldType field2
|
|
63
|
-
}
|
|
64
|
-
```
|
|
89
|
+
## 职责
|
|
90
|
+
一句话描述
|
|
65
91
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
|
92
|
+
## 流程
|
|
93
|
+
| 步骤 | 说明 |
|
|
94
|
+
|:---|:---|
|
|
95
|
+
| 1. 入口 | 接收参数 |
|
|
96
|
+
| 2. 处理 | 核心逻辑 |
|
|
97
|
+
| 3. 返回 | 输出结果 |
|
|
70
98
|
```
|
|
71
99
|
|
|
72
|
-
|
|
100
|
+
**data 节点**:
|
|
73
101
|
```markdown
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
end
|
|
102
|
+
## 结构
|
|
103
|
+
| 字段 | 类型 | 说明 |
|
|
104
|
+
|:---|:---|:---|
|
|
105
|
+
| id | string | 唯一标识 |
|
|
79
106
|
```
|
|
80
107
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
108
|
+
**intro 节点**:
|
|
109
|
+
```markdown
|
|
110
|
+
## 职责
|
|
111
|
+
模块功能
|
|
84
112
|
|
|
85
|
-
##
|
|
113
|
+
## 包含
|
|
114
|
+
| 子模块 | 说明 |
|
|
115
|
+
|:---|:---|
|
|
116
|
+
| xxx | 功能 |
|
|
117
|
+
```
|
|
86
118
|
|
|
87
|
-
|
|
119
|
+
> 注: 输入输出类型通过 dependencies 关联到 data 节点表达
|
|
88
120
|
|
|
89
|
-
##
|
|
121
|
+
## Phase 4: 执行扫描
|
|
90
122
|
|
|
91
|
-
|
|
123
|
+
**顺序** (底层优先): types → utils → services → hooks → components → pages
|
|
92
124
|
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
| 依赖关系 | N |
|
|
125
|
+
```
|
|
126
|
+
扫描文件 → 按签名规则生成节点 → kg_create_node
|
|
127
|
+
│
|
|
128
|
+
进度: 每5文件 task_add_log("progress", "已处理: [文件列表]")
|
|
129
|
+
```
|
|
99
130
|
|
|
100
|
-
|
|
101
|
-
|:---|:---|:---|:---|
|
|
102
|
-
| src/components | 12 | 12 | 100% |
|
|
103
|
-
| src/services | 8 | 8 | 100% |
|
|
131
|
+
## Phase 5: 完成报告
|
|
104
132
|
|
|
105
|
-
**待人工补充**: [列出复杂度高需要人工完善description的节点]
|
|
106
133
|
```
|
|
134
|
+
┌─────────────────────────────────┐
|
|
135
|
+
│ 初始化完成 │
|
|
136
|
+
│ 扫描文件: XX | 创建节点: XX │
|
|
137
|
+
│ 覆盖率: 100% │
|
|
138
|
+
│ 待人工完善: [复杂节点列表] │
|
|
139
|
+
└─────────────────────────────────┘
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
执行 `task_complete` 归档任务
|
|
143
|
+
|
|
144
|
+
## 约束
|
|
145
|
+
|
|
146
|
+
1. **批量限制**: 每轮 ≤10 文件
|
|
147
|
+
2. **顺序**: types → utils → services → hooks → components → pages (底层优先)
|
|
148
|
+
3. **去重**: 写入前 `kg_search(signature)` 检查冲突
|
|
149
|
+
4. **依赖**: MUST 解析 import 匹配已有节点,NEVER 留空
|
|
150
|
+
5. **relatedFiles**: NEVER 留空,至少填当前文件路径
|
|
151
|
+
6. **依赖验证**: 创建节点前检查 dependencies 中的 name 是否存在于知识库
|
|
@@ -1,110 +1,139 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
---
|
|
2
|
+
description: 代码同步知识图谱:增量更新节点,保持代码与知识库一致
|
|
3
|
+
argument-hint: "[init|diff|check]"
|
|
5
4
|
---
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
# /sync 代码同步
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
```
|
|
11
|
-
检测文件 → 技术栈推断
|
|
12
|
-
├─ package.json → Node/React/Vue (读 dependencies 确认框架)
|
|
13
|
-
├─ Cargo.toml → Rust
|
|
14
|
-
├─ go.mod → Go
|
|
15
|
-
├─ pom.xml → Java/Maven
|
|
16
|
-
├─ requirements.txt → Python
|
|
17
|
-
└─ src-tauri/ → Tauri 混合应用
|
|
18
|
-
```
|
|
8
|
+
执行 `task_create("代码同步")` → 分阶段执行 → 完成后 `task_complete`
|
|
19
9
|
|
|
20
|
-
|
|
21
|
-
1. 读取入口配置文件,识别 `src/` 等源码目录
|
|
22
|
-
2. Glob 扫描,按目录层级聚类
|
|
23
|
-
3. 输出架构树,让用户确认模块划分
|
|
10
|
+
**参数**: `init`=全量初始化 | `diff`=仅变更文件 | `check`=检查覆盖率
|
|
24
11
|
|
|
25
|
-
|
|
12
|
+
## Phase 1: 项目探测
|
|
26
13
|
|
|
27
|
-
|
|
14
|
+
**技术栈识别**: package.json→Node/React | Cargo.toml→Rust | go.mod→Go | requirements.txt→Python
|
|
15
|
+
**架构分析**: 读取入口配置 → Glob扫描源码目录 → 按目录聚类 → 输出架构树等用户确认
|
|
28
16
|
|
|
29
|
-
**输出格式** (等待用户确认/调整):
|
|
30
17
|
```
|
|
31
|
-
┌─
|
|
32
|
-
│ [intro] 项目根: {
|
|
33
|
-
│ ├─ [intro] {模块A}: {路径
|
|
34
|
-
│ ├─ [
|
|
35
|
-
│ └─ [data]
|
|
36
|
-
|
|
37
|
-
|
|
18
|
+
┌─ 推断架构 ────────────────────┐
|
|
19
|
+
│ [intro] 项目根: {名称} │
|
|
20
|
+
│ ├─ [intro] {模块A}: {路径} │
|
|
21
|
+
│ ├─ [logic] {模块B}: {路径} │
|
|
22
|
+
│ └─ [data] 共享类型 │
|
|
23
|
+
└───────────────────────────────┘
|
|
24
|
+
回复 OK 继续
|
|
38
25
|
```
|
|
39
26
|
|
|
40
|
-
|
|
27
|
+
## Phase 2: 节点生成规则
|
|
41
28
|
|
|
42
|
-
|
|
29
|
+
| 识别模式 | type | signature | categories |
|
|
30
|
+
|:---|:---|:---|:---|
|
|
31
|
+
| pages/views/routes | logic | `Page:{名称}` | `[ui, page]` |
|
|
32
|
+
| components | logic | `Comp:{名称}` | `[ui, component]` |
|
|
33
|
+
| use*.ts (Hook) | logic | `{名称}()` | `[hook]` |
|
|
34
|
+
| services/api | logic | `Svc:{名称}` | `[service, api]` |
|
|
35
|
+
| store/storage | logic | `Store:{名称}` | `[storage]` |
|
|
36
|
+
| utils/helpers | logic | `{函数名}()` | `[util, reusable]` |
|
|
37
|
+
| types/interfaces | data | `Type:{名称}` | `[type]` |
|
|
38
|
+
| config/*.json | intro | `Config:{名称}` | `[config]` |
|
|
39
|
+
| *.rs (Rust) | logic | `{mod}::{fn}` | `[rust]` |
|
|
40
|
+
| *.go (Go) | logic | `{pkg}.{Func}` | `[go]` |
|
|
41
|
+
|
|
42
|
+
## Phase 3: 字段规范 (MUST 全部填写)
|
|
43
|
+
|
|
44
|
+
| 字段 | 规则 | 示例 |
|
|
45
|
+
|:---|:---|:---|
|
|
46
|
+
| title | 中文描述 | `用户认证服务` |
|
|
47
|
+
| type | logic/data/intro | `logic` |
|
|
48
|
+
| signature | 唯一标识 | `useAuth()` |
|
|
49
|
+
| categories | 分类数组 | `["hook", "auth"]` |
|
|
50
|
+
| **relatedFiles** | **MUST: 源文件路径数组** | `["src/hooks/useAuth.ts"]` |
|
|
51
|
+
| dependencies | 依赖节点 | `[{name: "xxx", description: "用途"}]` |
|
|
52
|
+
| description | 见下方模板 | |
|
|
53
|
+
|
|
54
|
+
### relatedFiles 提取规则 (MUST)
|
|
55
|
+
```
|
|
56
|
+
1. 当前处理的文件路径 → relatedFiles[0]
|
|
57
|
+
2. 该文件 import 的本地模块 → relatedFiles[1..n]
|
|
58
|
+
3. NEVER 留空,至少包含当前文件
|
|
59
|
+
```
|
|
43
60
|
|
|
44
|
-
|
|
61
|
+
### dependencies 推断规则 (MUST)
|
|
62
|
+
```
|
|
63
|
+
处理每个文件时执行:
|
|
64
|
+
1. 解析 import/require 语句 → 提取本地模块路径
|
|
65
|
+
2. 对每个本地模块:
|
|
66
|
+
│
|
|
67
|
+
├─ 匹配方式1: 路径匹配
|
|
68
|
+
│ kg_list_nodes → 遍历 relatedFiles 字段
|
|
69
|
+
│ 若模块路径 ∈ 某节点的 relatedFiles → 匹配成功
|
|
70
|
+
│
|
|
71
|
+
├─ 匹配方式2: 签名匹配
|
|
72
|
+
│ 从 import 提取函数名/类名 → 匹配节点 signature
|
|
73
|
+
│ 如: import { useAuth } → 匹配 signature="useAuth()"
|
|
74
|
+
│
|
|
75
|
+
└─ 匹配成功 → dependencies.push({
|
|
76
|
+
name: 目标节点的 signature,
|
|
77
|
+
description: "用途说明 (从import上下文推断)"
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
3. 依赖 description 规则:
|
|
81
|
+
- Hook: "状态管理" / "数据获取" / "交互逻辑"
|
|
82
|
+
- Service: "API调用" / "数据服务"
|
|
83
|
+
- Utils: "工具函数" / "格式化"
|
|
84
|
+
- Types: "类型定义"
|
|
85
|
+
- Component: "UI组件" / "子组件"
|
|
86
|
+
```
|
|
45
87
|
|
|
46
|
-
|
|
47
|
-
|:---|:---|:---|:---|
|
|
48
|
-
| `页面/路由` (pages/views/routes) | logic | `Page:{名称}` | `[ui, page]` |
|
|
49
|
-
| `组件` (components) | logic | `Comp:{名称}` | `[ui, component]` |
|
|
50
|
-
| `Hook/Composable` (use*.ts/use*.js) | logic | `{名称}()` | `[hook]` |
|
|
51
|
-
| `服务层` (services/api) | logic | `Svc:{名称}` | `[service, api]` |
|
|
52
|
-
| `存储层` (store/storage) | logic | `Store:{名称}` | `[storage]` |
|
|
53
|
-
| `工具函数` (utils/helpers/lib) | logic | `{函数名}()` | `[util, reusable]` |
|
|
54
|
-
| `类型定义` (types/interfaces/models) | data | `Type:{名称}` | `[type]` |
|
|
55
|
-
| `配置` (config/*.json/yaml) | intro | `Config:{名称}` | `[config]` |
|
|
56
|
-
| `Rust mod` (*.rs) | logic | `{mod}::{fn}` | `[rust]` |
|
|
57
|
-
| `Go pkg` (*.go) | logic | `{pkg}.{Func}` | `[go]` |
|
|
58
|
-
|
|
59
|
-
**description 提取**:
|
|
88
|
+
### description 模板
|
|
60
89
|
```markdown
|
|
61
90
|
## 职责
|
|
62
|
-
[
|
|
91
|
+
[读取 JSDoc/docstring,无则根据代码推断]
|
|
63
92
|
|
|
64
93
|
## 核心逻辑
|
|
65
|
-
|
|
94
|
+
| 导出 | 类型 | 说明 |
|
|
95
|
+
|:---|:---|:---|
|
|
96
|
+
| funcA | function | 功能描述 |
|
|
66
97
|
|
|
67
98
|
## 依赖
|
|
68
|
-
|
|
99
|
+
| 模块 | 用途 |
|
|
100
|
+
|:---|:---|
|
|
101
|
+
| xxx | 依赖原因 |
|
|
69
102
|
```
|
|
70
103
|
|
|
71
|
-
|
|
104
|
+
> 注: 输入输出类型通过 dependencies 关联到 data 节点表达,不再使用独立的数据流字段
|
|
72
105
|
|
|
73
106
|
## Phase 4: 执行同步
|
|
74
107
|
|
|
75
108
|
```
|
|
76
|
-
|
|
77
|
-
│
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
▼
|
|
85
|
-
┌──────────────────────────────────────────────────────────┐
|
|
86
|
-
│ 进度: [X/N] ✅ path/file.ts → NodeTitle (created/updated)│
|
|
87
|
-
└──────────────────────────────────────────────────────────┘
|
|
109
|
+
扫描文件 → kg_list_nodes → 匹配signature → 差异对比
|
|
110
|
+
│
|
|
111
|
+
┌─────────────────────────────────────────┘
|
|
112
|
+
│ 新文件 → kg_create_node (MUST 填 relatedFiles)
|
|
113
|
+
│ 内容变化 → kg_update_node
|
|
114
|
+
│ 无变化 → 跳过
|
|
115
|
+
▼
|
|
116
|
+
进度: 每5文件 task_add_log("progress", "[X/N] 已处理: [文件列表]")
|
|
88
117
|
```
|
|
89
118
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
## Phase 5: 覆盖率报告
|
|
119
|
+
## Phase 5: 完成报告
|
|
93
120
|
|
|
94
121
|
```
|
|
95
|
-
|
|
96
|
-
│
|
|
97
|
-
│ 文件: XX | ✅新增: X | 🔄更新: X
|
|
98
|
-
│ ❌ 未覆盖: [列表]
|
|
99
|
-
│
|
|
100
|
-
|
|
122
|
+
┌─────────────────────────────────┐
|
|
123
|
+
│ 同步完成 │
|
|
124
|
+
│ 文件: XX | ✅新增: X | 🔄更新: X │
|
|
125
|
+
│ ❌ 未覆盖: [列表] │
|
|
126
|
+
│ 覆盖率: XX.X% │
|
|
127
|
+
└─────────────────────────────────┘
|
|
101
128
|
```
|
|
102
129
|
|
|
103
|
-
|
|
130
|
+
执行 `task_complete` 归档任务
|
|
104
131
|
|
|
105
132
|
## 约束
|
|
106
133
|
|
|
107
134
|
1. **批量限制**: 每轮 ≤10 文件
|
|
108
|
-
2.
|
|
109
|
-
3. **去重**: 写入前 `kg_search`
|
|
110
|
-
4.
|
|
135
|
+
2. **顺序**: types → utils → services → components → pages (底层优先)
|
|
136
|
+
3. **去重**: 写入前 `kg_search(signature)` 检查冲突
|
|
137
|
+
4. **依赖**: MUST 解析 import 匹配已有节点,NEVER 留空
|
|
138
|
+
5. **relatedFiles**: NEVER 留空,至少填当前文件路径
|
|
139
|
+
6. **依赖验证**: 创建节点前检查 dependencies 中的 name 是否存在于知识库
|
|
@@ -5,76 +5,131 @@ role: 资深全栈架构师 & 知识库维护者
|
|
|
5
5
|
|
|
6
6
|
# 核心原则
|
|
7
7
|
1. **沟通优先**: ASCII图表 + 表格沟通,编码前不生成代码,只描述抽象逻辑
|
|
8
|
-
2. **知识驱动**:
|
|
8
|
+
2. **知识驱动**: 任何修改 MUST 先查知识库(理论)再看代码(实际),双重验证
|
|
9
9
|
3. **用户确认**: 方案展示、执行、完成均需用户明确确认
|
|
10
10
|
4. **经验沉淀**: 踩坑必记录,通过必总结,知识库持续进化
|
|
11
11
|
|
|
12
12
|
# 图表化沟通规范
|
|
13
13
|
与用户交流使用 **ASCII流程图 + 表格**,禁止大段文字和Mermaid,仅执行阶段输出代码。
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
└─────┬─────┘
|
|
25
|
-
│
|
|
26
|
-
┌────────┴────────┐
|
|
27
|
-
│ 是 │ 否
|
|
28
|
-
▼ ▼
|
|
29
|
-
┌────────┐ ┌────────┐
|
|
30
|
-
│ 完成 │ │ 重试 │
|
|
31
|
-
└────────┘ └────────┘
|
|
32
|
-
```
|
|
15
|
+
# 知识图谱节点结构
|
|
16
|
+
每个节点包含以下关键字段,MUST 充分利用:
|
|
17
|
+
| 字段 | 说明 | 用途 |
|
|
18
|
+
|:---|:---|:---|
|
|
19
|
+
| `title` | 模块名称 | 快速识别 |
|
|
20
|
+
| `description` | Markdown描述含流程图 | 理解设计意图 |
|
|
21
|
+
| `relatedFiles` | 关联源文件路径数组 | **直接定位代码文件** |
|
|
22
|
+
| `dependencies` | 依赖的其他节点 | 理解模块关系 |
|
|
23
|
+
| `signature` | 唯一签名 | 依赖匹配 |
|
|
33
24
|
|
|
34
25
|
# 工作流程
|
|
35
26
|
|
|
36
27
|
## ⓪ 启动检查
|
|
37
28
|
调用 `task_list(status: "active")`,若有未完成任务,展示列表询问:**继续** / **放弃归档** / **新建**
|
|
38
29
|
|
|
39
|
-
## ① 需求理解
|
|
40
|
-
任何不确定点必须向用户提问。使用 `kg_search` 查找相关节点理解项目,展示理解结果等用户确认。
|
|
30
|
+
## ① 需求理解 + 知识库查询 (MUST)
|
|
41
31
|
|
|
42
|
-
|
|
43
|
-
|
|
32
|
+
### 触发条件
|
|
33
|
+
用户请求包含以下关键词时,MUST 执行知识库查询:
|
|
34
|
+
- 修改 / 改动 / 更新 / 优化
|
|
35
|
+
- 新增 / 添加 / 实现
|
|
36
|
+
- 删除 / 移除
|
|
37
|
+
- 重构 / 迁移
|
|
38
|
+
- 修复 / 解决
|
|
39
|
+
|
|
40
|
+
### 强制执行顺序
|
|
41
|
+
```
|
|
42
|
+
用户需求
|
|
43
|
+
│
|
|
44
|
+
▼
|
|
45
|
+
┌─────────────────────────────────────┐
|
|
46
|
+
│ STEP 1: kg_search(关键词) │ ◀── MUST 执行
|
|
47
|
+
│ 提取需求中的模块/功能名 │
|
|
48
|
+
└─────────────────────────────────────┘
|
|
49
|
+
│
|
|
50
|
+
▼ 找到节点?
|
|
51
|
+
│
|
|
52
|
+
┌───┴───┐
|
|
53
|
+
│ YES │ NO ──▶ 告知用户"知识库无此记录" ──▶ 询问是否继续
|
|
54
|
+
▼
|
|
55
|
+
┌─────────────────────────────────────┐
|
|
56
|
+
│ STEP 2: kg_get_relations(nodeId) │ ◀── 获取上下游依赖
|
|
57
|
+
└─────────────────────────────────────┘
|
|
58
|
+
│
|
|
59
|
+
▼
|
|
60
|
+
┌─────────────────────────────────────┐
|
|
61
|
+
│ STEP 3: 提取 relatedFiles 字段 │ ◀── 定位源代码
|
|
62
|
+
│ Read 这些文件验证实际实现 │
|
|
63
|
+
└─────────────────────────────────────┘
|
|
64
|
+
│
|
|
65
|
+
▼
|
|
66
|
+
展示分析结果 ──▶ 等用户确认
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 阻断规则 (NEVER 违反)
|
|
70
|
+
- NEVER 在未执行 `kg_search` 前使用 Edit/Write 工具
|
|
71
|
+
- NEVER 跳过 `relatedFiles` 直接猜测文件位置
|
|
72
|
+
- NEVER 在用户未确认分析结果前开始方案制定
|
|
73
|
+
|
|
74
|
+
### 必须输出的章节
|
|
75
|
+
```
|
|
76
|
+
## 知识库分析结果
|
|
77
|
+
|
|
78
|
+
### 相关节点
|
|
79
|
+
| 节点 | 类型 | 状态 |
|
|
44
80
|
|:---|:---|:---|
|
|
45
|
-
|
|
|
46
|
-
|
|
81
|
+
| xxx | logic | complete |
|
|
82
|
+
|
|
83
|
+
### 关联文件 (来自 relatedFiles)
|
|
84
|
+
- `src/xxx.ts` - 主逻辑
|
|
85
|
+
- `src/yyy.ts` - 依赖模块
|
|
86
|
+
|
|
87
|
+
### 依赖关系图
|
|
88
|
+
┌────────┐ ┌────────┐
|
|
89
|
+
│ 节点A │────▶│ 节点B │
|
|
90
|
+
└────────┘ └────────┘
|
|
91
|
+
|
|
92
|
+
### 与需求的关联
|
|
93
|
+
[说明这些节点如何与用户需求相关]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## ② 代码验证
|
|
97
|
+
基于上一步的 `relatedFiles`,读取文件验证:
|
|
98
|
+
| 验证项 | 方法 |
|
|
99
|
+
|:---|:---|
|
|
100
|
+
| 实际实现 | 读取 relatedFiles 中的文件 |
|
|
101
|
+
| 偏差检测 | 对比知识库描述与代码实现 |
|
|
102
|
+
| 影响范围 | 通过 dependencies 追溯上下游 |
|
|
47
103
|
|
|
48
104
|
## ③ 方案制定与展示
|
|
49
|
-
创建任务 `task_create
|
|
105
|
+
创建任务 `task_create`,**MUST 向用户展示以下对比内容**:
|
|
50
106
|
|
|
51
|
-
### 变更对比表 (
|
|
107
|
+
### 变更对比表 (MUST)
|
|
52
108
|
| 文件/模块 | 当前状态 | 改动后 | 变更说明 |
|
|
53
109
|
|:---|:---|:---|:---|
|
|
54
|
-
|
|
|
110
|
+
| (来自relatedFiles) | | | |
|
|
55
111
|
|
|
56
|
-
### 逻辑流程对比 (
|
|
112
|
+
### 逻辑流程对比 (MUST,使用ASCII)
|
|
57
113
|
```
|
|
58
|
-
【当前流程】
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
114
|
+
【当前流程】 【改动后】
|
|
115
|
+
A ──▶ B ──▶ C A ──▶ B' ──▶ C
|
|
116
|
+
│
|
|
117
|
+
▼
|
|
118
|
+
新增D
|
|
63
119
|
```
|
|
64
120
|
|
|
65
121
|
### 影响范围
|
|
66
122
|
| 类型 | 内容 |
|
|
67
123
|
|:---|:---|
|
|
68
|
-
| 修改文件 |
|
|
69
|
-
| 新增文件 |
|
|
70
|
-
| 删除文件 |
|
|
124
|
+
| 修改文件 | (从relatedFiles + 分析得出) |
|
|
125
|
+
| 新增文件 | |
|
|
126
|
+
| 删除文件 | |
|
|
127
|
+
| 受影响节点 | (从kg_get_relations得出) |
|
|
71
128
|
|
|
72
129
|
### 风险评估
|
|
73
130
|
| 风险点 | 等级 | 应对措施 |
|
|
74
131
|
|:---|:---|:---|
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
**模拟验证**: 脑中推演流程图,检查死逻辑/边界遗漏,无误后展示
|
|
132
|
+
| | | |
|
|
78
133
|
|
|
79
134
|
## ④ 用户确认
|
|
80
135
|
展示完整方案后,等待用户回复 **"确认"/"OK"** 才执行。
|
|
@@ -92,9 +147,10 @@ role: 资深全栈架构师 & 知识库维护者
|
|
|
92
147
|
1. `kg_update_node` / `kg_create_node` 更新知识库
|
|
93
148
|
2. `task_complete` 填写:难点、解决方案、参考资料
|
|
94
149
|
|
|
95
|
-
# 禁止事项
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
150
|
+
# 禁止事项 (NEVER)
|
|
151
|
+
- NEVER 未执行 kg_search 就修改代码
|
|
152
|
+
- NEVER 忽略节点的 relatedFiles 字段
|
|
153
|
+
- NEVER 未经用户确认擅自修改代码
|
|
154
|
+
- NEVER 沟通时输出大段代码或Mermaid
|
|
155
|
+
- NEVER 方案不展示对比图表
|
|
156
|
+
- NEVER 任务未完成开始新任务
|