@ppdocs/mcp 3.1.2 → 3.1.4

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 CHANGED
@@ -47,8 +47,12 @@ npx @ppdocs/mcp init -p <项目ID> -k <密钥>
47
47
 
48
48
  这会自动:
49
49
  - 创建 `.ppdocs` 配置文件
50
- - 创建 `.mcp.json` MCP 配置
51
- - 安装工作流模板到 `.claude/`
50
+ - 检测工作区 IDE 配置目录,自动安装对应模板:
51
+ - `.claude/` → Claude Code 工作流模板 + MCP 权限
52
+ - `.cursor/` → Cursor MCP 配置 + .cursorrules
53
+ - `.gemini/` → Antigravity MCP 配置 + AGENTS.md
54
+ - `.kiro/` → Kiro MCP 配置 + Agent 规则
55
+ - 自动检测并注册 CLI MCP (claude/codex/gemini)
52
56
 
53
57
  ### 3. 配置 Claude Desktop
54
58
 
package/dist/cli.js CHANGED
@@ -7,6 +7,7 @@ import * as path from 'path';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { execSync } from 'child_process';
9
9
  import { generateUser } from './config.js';
10
+ import { PpdocsApiClient } from './storage/httpClient.js';
10
11
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
12
  const TEMPLATES_DIR = path.join(__dirname, '..', 'templates');
12
13
  function parseArgs(args) {
@@ -62,6 +63,20 @@ function parseArgs(args) {
62
63
  else if (arg === '--codex') {
63
64
  opts.codex = true;
64
65
  }
66
+ else if (arg === '--from') {
67
+ if (i + 1 >= args.length || args[i + 1].startsWith('-')) {
68
+ console.error('Error: --from requires a project ID');
69
+ return null;
70
+ }
71
+ opts.from = args[++i];
72
+ }
73
+ else if (arg === '--sync') {
74
+ if (i + 1 >= args.length || args[i + 1].startsWith('-')) {
75
+ console.error('Error: --sync requires a project ID');
76
+ return null;
77
+ }
78
+ opts.sync = args[++i];
79
+ }
65
80
  }
66
81
  if (!opts.project || !opts.key)
67
82
  return null;
@@ -86,10 +101,14 @@ Options:
86
101
  --port API port (default: 20001)
87
102
  --api API host (default: localhost)
88
103
  --codex Codex mode: generate AGENTS.md instead of .claude/
104
+ --from <id> Pull IDE configs from a template project
105
+ --sync <id> Sync knowledge base docs from a source project to ./docs/ppdocs/
89
106
 
90
107
  Example:
91
108
  npx @ppdocs/mcp init -p myproject -k abc123xyz
92
109
  npx @ppdocs/mcp init -p myproject -k abc123xyz --codex
110
+ npx @ppdocs/mcp init -p myproject -k abc123xyz --from _templates
111
+ npx @ppdocs/mcp init -p myproject -k abc123xyz --sync shared-rules
93
112
  `);
94
113
  }
95
114
  export function runCli(args) {
@@ -101,7 +120,10 @@ export function runCli(args) {
101
120
  showHelp();
102
121
  process.exit(1);
103
122
  }
104
- initProject(opts);
123
+ initProject(opts).catch(e => {
124
+ console.error(`❌ Init failed: ${e}`);
125
+ process.exit(1);
126
+ });
105
127
  return true;
106
128
  }
107
129
  if (cmd === '--help' || cmd === '-h' || cmd === 'help') {
@@ -110,7 +132,7 @@ export function runCli(args) {
110
132
  }
111
133
  return false; // Not a CLI command, run as MCP server
112
134
  }
113
- function initProject(opts) {
135
+ async function initProject(opts) {
114
136
  const cwd = process.cwd();
115
137
  const apiUrl = `http://${opts.api}:${opts.port}/api/${opts.project}/${opts.key}`;
116
138
  // Create .ppdocs config
@@ -131,19 +153,48 @@ function initProject(opts) {
131
153
  }
132
154
  fs.writeFileSync(ppdocsPath, JSON.stringify(ppdocsConfig, null, 2));
133
155
  console.log(`✅ Created ${ppdocsPath}`);
134
- // Install workflow templates
135
- if (opts.codex) {
136
- installCodexTemplates(cwd);
137
- }
138
- else {
156
+ // Install workflow templates based on IDE detection
157
+ const detectedIdes = detectIDEs(cwd);
158
+ let hasIdeDir = false;
159
+ if (detectedIdes.includes('claude')) {
139
160
  installClaudeTemplates(cwd);
161
+ hasIdeDir = true;
162
+ }
163
+ if (detectedIdes.includes('cursor')) {
164
+ installCursorTemplates(cwd);
165
+ hasIdeDir = true;
166
+ }
167
+ if (detectedIdes.includes('antigravity')) {
168
+ installAntigravityTemplates(cwd);
169
+ hasIdeDir = true;
170
+ }
171
+ if (detectedIdes.includes('kiro')) {
172
+ installKiroTemplates(cwd);
173
+ hasIdeDir = true;
174
+ }
175
+ // Fallback behavior: if no specific IDE config directories found
176
+ if (!hasIdeDir) {
177
+ if (opts.codex) {
178
+ installCodexTemplates(cwd);
179
+ }
180
+ else {
181
+ installClaudeTemplates(cwd); // Default to Claude templates
182
+ }
140
183
  }
141
184
  // 自动检测并注册 MCP
142
185
  const registered = autoRegisterMcp(apiUrl, opts.user);
143
- // 如果没有检测到任何 AI CLI,创建 .mcp.json 作为备用
144
- if (!registered) {
186
+ // 如果没有检测到任何 AI CLI,并且也没有检测到配置文件夹,创建 .mcp.json 作为备用
187
+ if (!registered && !hasIdeDir) {
145
188
  createMcpJson(cwd);
146
189
  }
190
+ // --from: 从模板项目拉取 IDE 配置文件
191
+ if (opts.from) {
192
+ await pullTemplateProject(cwd, apiUrl, opts.from);
193
+ }
194
+ // --sync: 从源项目同步知识库文档到本地
195
+ if (opts.sync) {
196
+ await syncKnowledgeBase(cwd, apiUrl, opts.sync);
197
+ }
147
198
  console.log(`
148
199
  🎉 Done! ppdocs MCP configured for project: ${opts.project}
149
200
  User: ${opts.user}
@@ -151,6 +202,65 @@ function initProject(opts) {
151
202
  Restart your AI tool to use ppdocs knowledge graph.
152
203
  `);
153
204
  }
205
+ /** 从模板项目拉取 IDE 配置到当前项目目录 */
206
+ async function pullTemplateProject(cwd, apiUrl, templateId) {
207
+ console.log(`📦 Pulling IDE configs from template project: ${templateId}...`);
208
+ try {
209
+ const client = new PpdocsApiClient(apiUrl);
210
+ const files = await client.crossListFiles(templateId);
211
+ if (files.length === 0) {
212
+ console.log(`⚠️ Template project "${templateId}" has no files (upload files via the desktop app first)`);
213
+ return;
214
+ }
215
+ const result = await client.crossDownload(templateId, '/', cwd);
216
+ console.log(`✅ Pulled ${result.fileCount} files from template project "${templateId}"`);
217
+ }
218
+ catch (e) {
219
+ console.log(`⚠️ Failed to pull from template project: ${e}`);
220
+ }
221
+ }
222
+ /** 从源项目同步知识库文档到本地 ./docs/ppdocs/ */
223
+ async function syncKnowledgeBase(cwd, apiUrl, sourceId) {
224
+ console.log(`📚 Syncing knowledge base from project: ${sourceId}...`);
225
+ try {
226
+ const client = new PpdocsApiClient(apiUrl);
227
+ const docs = await client.crossListDocs(sourceId);
228
+ const docNodes = docs.filter(d => !d.isDir);
229
+ if (docNodes.length === 0) {
230
+ console.log(`⚠️ Project "${sourceId}" has no knowledge base documents`);
231
+ return;
232
+ }
233
+ const docsDir = path.join(cwd, 'docs', 'ppdocs', sourceId);
234
+ fs.mkdirSync(docsDir, { recursive: true });
235
+ let synced = 0;
236
+ for (const node of docNodes) {
237
+ const doc = await client.crossGetDoc(sourceId, node.path);
238
+ if (!doc)
239
+ continue;
240
+ // 将文档路径转为本地文件路径 (e.g. "/前端/组件/Modal" → "前端/组件/Modal.md")
241
+ const safePath = node.path.replace(/^\//, '').replace(/[<>:"|?*]/g, '_');
242
+ const localFile = path.join(docsDir, `${safePath}.md`);
243
+ const localDir = path.dirname(localFile);
244
+ if (!fs.existsSync(localDir)) {
245
+ fs.mkdirSync(localDir, { recursive: true });
246
+ }
247
+ // 生成 Markdown 文件内容
248
+ const content = [
249
+ `# ${node.name}`,
250
+ '',
251
+ doc.summary ? `> ${doc.summary}` : '',
252
+ '',
253
+ doc.content || '',
254
+ ].filter(Boolean).join('\n');
255
+ fs.writeFileSync(localFile, content, 'utf-8');
256
+ synced++;
257
+ }
258
+ console.log(`✅ Synced ${synced} documents from "${sourceId}" to docs/ppdocs/${sourceId}/`);
259
+ }
260
+ catch (e) {
261
+ console.log(`⚠️ Failed to sync knowledge base: ${e}`);
262
+ }
263
+ }
154
264
  /** 检测命令是否存在 */
155
265
  function commandExists(cmd) {
156
266
  try {
@@ -233,9 +343,8 @@ function autoRegisterMcp(apiUrl, user) {
233
343
  console.log(`✅ Registered MCP for: ${detected.join(', ')}`);
234
344
  return true;
235
345
  }
236
- /** 创建 .mcp.json (手动配置备用) */
237
- function createMcpJson(cwd) {
238
- const mcpPath = path.join(cwd, '.mcp.json');
346
+ /** 在指定路径创建或更新 mcp.json 配置 */
347
+ function createMcpConfigAt(mcpPath, autoCreatedTemplate) {
239
348
  let mcpConfig = {};
240
349
  if (fs.existsSync(mcpPath)) {
241
350
  try {
@@ -248,14 +357,23 @@ function createMcpJson(cwd) {
248
357
  // Windows 需要 cmd /c 包装才能执行 npx
249
358
  const isWindows = process.platform === 'win32';
250
359
  const ppdocsServer = isWindows
251
- ? { command: 'cmd', args: ['/c', 'npx', '@ppdocs/mcp@latest'] }
252
- : { command: 'npx', args: ['@ppdocs/mcp@latest'] };
360
+ ? { command: 'cmd', args: ['/c', 'npx', '-y', '@ppdocs/mcp@latest'] }
361
+ : { command: 'npx', args: ['-y', '@ppdocs/mcp@latest'] };
253
362
  mcpConfig.mcpServers = {
254
363
  ...(mcpConfig.mcpServers || {}),
255
- ppdocs: ppdocsServer,
364
+ "ppdocs-kg": ppdocsServer,
256
365
  };
366
+ // 确保父目录存在
367
+ const parentDir = path.dirname(mcpPath);
368
+ if (!fs.existsSync(parentDir)) {
369
+ fs.mkdirSync(parentDir, { recursive: true });
370
+ }
257
371
  fs.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
258
- console.log(`✅ Created ${mcpPath}`);
372
+ console.log(`✅ Configured MCP in ${mcpPath}`);
373
+ }
374
+ /** 创建 .mcp.json (手动配置备用) */
375
+ function createMcpJson(cwd) {
376
+ createMcpConfigAt(path.join(cwd, '.mcp.json'));
259
377
  }
260
378
  /** 递归复制目录 */
261
379
  function copyDirRecursive(src, dest) {
@@ -363,13 +481,65 @@ function installClaudeTemplates(cwd) {
363
481
  }
364
482
  /** 安装 Codex 模板 (生成 AGENTS.md) */
365
483
  function installCodexTemplates(cwd) {
484
+ generateAgentsMd(cwd);
485
+ }
486
+ /** 生成 AGENTS.md 工具函数 (去重) */
487
+ function generateAgentsMd(cwd) {
366
488
  const srcPrompt = path.join(TEMPLATES_DIR, 'hooks', 'SystemPrompt.md');
367
489
  const destAgents = path.join(cwd, 'AGENTS.md');
368
- if (fs.existsSync(srcPrompt)) {
490
+ if (fs.existsSync(srcPrompt) && !fs.existsSync(destAgents)) {
369
491
  fs.copyFileSync(srcPrompt, destAgents);
370
- console.log(`✅ Created AGENTS.md (Codex mode)`);
492
+ console.log(`✅ Created AGENTS.md`);
371
493
  }
372
- else {
494
+ else if (!fs.existsSync(srcPrompt)) {
373
495
  console.log(`⚠️ SystemPrompt.md template not found`);
374
496
  }
375
497
  }
498
+ /** 安装 Cursor 模板 */
499
+ function installCursorTemplates(cwd) {
500
+ // 1. 生成 Cursor MCP 配置
501
+ createMcpConfigAt(path.join(cwd, '.cursor', 'mcp.json'));
502
+ // 2. 生成 .cursorrules 提示词
503
+ const srcRules = path.join(TEMPLATES_DIR, 'cursorrules.md');
504
+ const destRules = path.join(cwd, '.cursorrules');
505
+ if (fs.existsSync(srcRules) && !fs.existsSync(destRules)) {
506
+ fs.copyFileSync(srcRules, destRules);
507
+ console.log(`✅ Created .cursorrules`);
508
+ }
509
+ }
510
+ /** 安装 Antigravity (Gemini IDE) 模板 */
511
+ function installAntigravityTemplates(cwd) {
512
+ // 1. 填充 .gemini/settings.json
513
+ createMcpConfigAt(path.join(cwd, '.gemini', 'settings.json'));
514
+ // 2. 生成 AGENTS.md
515
+ generateAgentsMd(cwd);
516
+ }
517
+ /** 安装 Kiro 模板 */
518
+ function installKiroTemplates(cwd) {
519
+ // 1. 生成 Kiro MCP 配置
520
+ createMcpConfigAt(path.join(cwd, '.kiro', 'settings', 'mcp.json'));
521
+ // 2. 生成 Kiro Agent 规则
522
+ const kiroRulesDir = path.join(cwd, '.kiro', 'rules');
523
+ if (!fs.existsSync(kiroRulesDir)) {
524
+ fs.mkdirSync(kiroRulesDir, { recursive: true });
525
+ }
526
+ const srcRules = path.join(TEMPLATES_DIR, 'kiro-rules', 'ppdocs.md');
527
+ const destRules = path.join(kiroRulesDir, 'ppdocs.md');
528
+ if (fs.existsSync(srcRules) && !fs.existsSync(destRules)) {
529
+ fs.copyFileSync(srcRules, destRules);
530
+ console.log(`✅ Created .kiro/rules/ppdocs.md`);
531
+ }
532
+ }
533
+ /** 检测当前工作区包含的 IDE */
534
+ function detectIDEs(cwd) {
535
+ const ides = [];
536
+ if (fs.existsSync(path.join(cwd, '.claude')))
537
+ ides.push('claude');
538
+ if (fs.existsSync(path.join(cwd, '.cursor')))
539
+ ides.push('cursor');
540
+ if (fs.existsSync(path.join(cwd, '.gemini')))
541
+ ides.push('antigravity');
542
+ if (fs.existsSync(path.join(cwd, '.kiro')))
543
+ ides.push('kiro');
544
+ return ides;
545
+ }
@@ -407,6 +407,65 @@ export function registerTools(server, projectId, _user) {
407
407
  const lines = docs.map(d => `- ${d.path} (${d.status || '已完成'}): ${d.summary || '无简介'}`);
408
408
  return wrap(`找到 ${docs.length} 个文档:\n\n${lines.join('\n')}`);
409
409
  });
410
+ // 12. 跨项目复制文档到当前项目
411
+ server.tool('kg_copy_node', '从其他项目复制文档到当前项目。支持单个或批量复制,可指定新路径。用于跨项目协作:拉取别的项目的知识文档到当前项目', {
412
+ sourceProject: z.string().describe('源项目ID或名称(从kg_list_projects获取)'),
413
+ sourcePath: z.union([z.string(), z.array(z.string())]).describe('源文档路径(单个或数组,如"/架构/数据流"或["/架构/数据流","/MCP/tools"])'),
414
+ targetPath: z.string().optional().describe('目标路径前缀(如"/参考/项目B")。不填则保持原路径'),
415
+ }, async (args) => {
416
+ const decoded = decodeObjectStrings(args);
417
+ const paths = Array.isArray(decoded.sourcePath) ? decoded.sourcePath : [decoded.sourcePath];
418
+ const results = [];
419
+ for (const srcPath of paths) {
420
+ try {
421
+ // 从源项目读取文档
422
+ const doc = await storage.crossGetDoc(decoded.sourceProject, srcPath);
423
+ if (!doc) {
424
+ results.push({ path: srcPath, success: false, error: '源文档不存在' });
425
+ continue;
426
+ }
427
+ // 计算目标路径
428
+ const destPath = decoded.targetPath
429
+ ? `${decoded.targetPath.replace(/\/$/, '')}${srcPath}`
430
+ : srcPath;
431
+ // 检查目标是否已存在
432
+ const existing = await storage.getDoc(projectId, destPath);
433
+ if (existing) {
434
+ // 已存在则更新
435
+ await storage.updateDoc(projectId, destPath, {
436
+ summary: doc.summary,
437
+ content: doc.content,
438
+ });
439
+ results.push({ path: destPath, success: true });
440
+ }
441
+ else {
442
+ // 不存在则创建
443
+ await storage.createDoc(projectId, destPath, {
444
+ summary: doc.summary,
445
+ content: doc.content,
446
+ status: doc.status,
447
+ });
448
+ results.push({ path: destPath, success: true });
449
+ }
450
+ }
451
+ catch (e) {
452
+ results.push({ path: srcPath, success: false, error: String(e) });
453
+ }
454
+ }
455
+ const successCount = results.filter(r => r.success).length;
456
+ const failedItems = results.filter(r => !r.success);
457
+ if (paths.length === 1) {
458
+ if (results[0].success) {
459
+ return wrap(`✅ 已复制文档: ${results[0].path}\n\n来源: [${decoded.sourceProject}] ${paths[0]}`);
460
+ }
461
+ return wrap(`❌ 复制失败: ${results[0].error}`);
462
+ }
463
+ let msg = `✅ 批量复制完成: ${successCount}/${paths.length} 成功`;
464
+ if (failedItems.length > 0) {
465
+ msg += `\n❌ 失败:\n${failedItems.map(f => ` - ${f.path}: ${f.error}`).join('\n')}`;
466
+ }
467
+ return wrap(msg);
468
+ });
410
469
  // ===================== 任务管理 =====================
411
470
  // 7. 创建任务
412
471
  server.tool('task_create', '创建开发任务', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ppdocs/mcp",
3
- "version": "3.1.2",
3
+ "version": "3.1.4",
4
4
  "description": "ppdocs MCP Server - Knowledge Graph for Claude",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,6 +10,8 @@
10
10
  | `hooks/SystemPrompt.md` | 系统提示词模板 | `.claude/hooks/SystemPrompt.md` |
11
11
  | `commands/pp/` | Claude Code 自定义命令 | `.claude/commands/pp/` |
12
12
  | `AGENT.md` | Codex/通用 Agent 提示词 | `./AGENTS.md` |
13
+ | `cursorrules.md` | Cursor IDE 提示词 | `.cursorrules` |
14
+ | `kiro-rules/ppdocs.md` | Kiro IDE Agent 规则 | `.kiro/rules/ppdocs.md` |
13
15
 
14
16
  ## 安装命令
15
17
 
@@ -23,15 +25,19 @@ npx @ppdocs/mcp init -p <projectId> -k <key> --codex
23
25
 
24
26
  ## 安装流程
25
27
 
26
- ### 默认模式 (Claude Code)
28
+ ### 自动检测模式 (默认)
27
29
 
28
- 1. 生成 `.ppdocs` 配置文件 (api/projectId/key)
29
- 2. 复制 `templates/commands/pp/` → `.claude/commands/pp/`
30
- 3. 复制 `templates/hooks/` → `.claude/hooks/`
31
- 4. 动态生成 hooks 配置 → 合并到 `.claude/settings.json`
32
- 5. 自动检测并注册 MCP
30
+ CLI 通过 `detectIDEs()` 扫描项目目录,自动为检测到的 IDE 安装对应模板:
33
31
 
34
- ### Codex 模式
32
+ | 检测目录 | 安装动作 |
33
+ |---------|--------|
34
+ | `.claude/` | 复制 commands/pp/ + hooks/ → `.claude/`,生成 settings.json |
35
+ | `.cursor/` | 生成 `.cursor/mcp.json` + `.cursorrules` |
36
+ | `.gemini/` | 填充 `.gemini/settings.json` + 生成 `AGENTS.md` |
37
+ | `.kiro/` | 生成 `.kiro/settings/mcp.json` + `.kiro/rules/ppdocs.md` |
38
+ | 未检测到 | Fallback: Claude 模板 (默认) 或 `--codex` 走 Codex 模板 |
39
+
40
+ ### Codex 模式 (--codex)
35
41
 
36
42
  1. 生成 `.ppdocs` 配置文件
37
43
  2. 复制 `templates/hooks/SystemPrompt.md` → `./AGENTS.md`
@@ -0,0 +1,102 @@
1
+ 你是严谨的软件架构师,围绕**用户知识图谱软件**工作,确保每个变动有据可查,每次成功沉淀为知识节点。
2
+
3
+ ## 核心宪法
4
+ | 原则 | 要求 |
5
+ |:---|:---|
6
+ | **知识图谱中心** | 方案制定前检索图谱+代码双重验证;任务结束提示沉淀至图谱 |
7
+ | **任务驱动开发** | 复杂任务必须 `task_create`;过程记录 `task_add_log`;完成 `task_complete` |
8
+ | **规则引用** | 编码前读 `codeStyle`;测试前读 `testRules`;审查前读 `reviewRules` |
9
+ | **绝对真实性** | 禁用 faker/模拟数据,必须真实环境验证 |
10
+ | **沟通可视化** | 禁纯文字/Mermaid代码;强制 ASCII流程图 + Markdown表格 |
11
+ | **极简模块化** | 拆解为原子函数,清理注释旧代码/Debug日志 |
12
+
13
+ ---
14
+
15
+ ## 任务生命周期
16
+ ```
17
+ task_create → task_add_log(progress/issue/solution/reference) → task_complete
18
+ ```
19
+ | 日志类型 | 用途 | 示例 |
20
+ |:---|:---|:---|
21
+ | `progress` | 阶段进度 | "完成Step2逻辑设计" |
22
+ | `issue` | 遇到问题 | "API返回格式不一致" |
23
+ | `solution` | 解决方案 | "添加数据转换层" |
24
+ | `reference` | 参考资料 | "参考 xxx 文档" |
25
+
26
+ ---
27
+
28
+ ## 标准流程 (SOP)
29
+
30
+ ### Step 1: 分析与澄清
31
+ 1. 接收需求,识别意图
32
+ 2. `kg_search` 检索现有节点/历史坑点 (读取 bugfixes)
33
+ 3. `kg_get_rules()` 获取项目规则
34
+ 4. 有歧义则列选项供用户选择
35
+
36
+ **输出**: 需求确认清单 (表格)
37
+
38
+ ### Step 2: 逻辑设计
39
+ 1. 结合图谱+代码设计方案
40
+ 2. `kg_get_rules(ruleType:"codeStyle")` 确认编码规范
41
+ 3. 检查现有复用函数,拒绝重复建设
42
+ 4. 大型任务: `task_create`
43
+
44
+ **输出**: ASCII流程图 + 对比表 + 子任务列表
45
+ **里程碑**: 等待用户确认 (不写代码)
46
+
47
+ ### Step 3: 模块化编码
48
+ **前置**: 用户确认方案
49
+ 1. `task_add_log(progress, "开始编码")`
50
+ 2. 优先编写/更新工具函数,再业务组装
51
+ 3. 遵循 codeStyle 规则
52
+ 4. 清理现场,无残留代码
53
+
54
+ **输出**: 结构清晰的代码
55
+
56
+ ### Step 4: 真实验证
57
+ 1. `kg_get_rules(ruleType:"testRules")` 获取测试规则
58
+ 2. 在 `tests/` 对应目录创建测试
59
+ 3. 真实环境运行,验证输出
60
+ 4. 失败时: `task_add_log(issue, "xxx失败")` → 回溯Step2
61
+
62
+ **严禁**: "测试环境所以失败"借口
63
+
64
+ ### Step 5: 审查与沉淀
65
+ 1. `kg_get_rules(ruleType:"reviewRules")` 获取审查规则
66
+ 2. 审查目录结构/代码简洁度
67
+ 3. 发现BUG → `kg_update_node` 写入 bugfixes
68
+ 4. 新逻辑 → `kg_create_node` 或 `kg_update_node` (追加 versions)
69
+ 5. `task_complete({summary, difficulties, solutions, references})`
70
+
71
+ **输出**: 交付确认 + 图谱更新清单
72
+
73
+ ---
74
+
75
+ ## 异常处理
76
+ | 场景 | 反应 |
77
+ |:---|:---|
78
+ | Step4 测试失败 | 停止 → 分析日志 → task_add_log(issue) → 回溯Step2 → 修正 → 重测 |
79
+ | 发现历史BUG | 读取节点 bugfixes 参考历史方案 |
80
+ | 重复造轮子 | 终止 → 指出现有实现 → 要求复用 |
81
+
82
+ ---
83
+
84
+ ## 沟通协议
85
+ **逻辑流程图 (ASCII)**:
86
+ ```
87
+ +----------+ +----------+ +----------+
88
+ | Input | --> | Logic A | --> | Output |
89
+ | (KG DB) | | (func) | | (Result) |
90
+ +----------+ +----+-----+ +----------+
91
+ |
92
+ +----v-----+
93
+ | Logic B |
94
+ | (error) |
95
+ +----------+
96
+ ```
97
+
98
+ **对比表**:
99
+ | 维度 | As-Is | To-Be | 风险 |
100
+ |:---|:---|:---|:---|
101
+ | 复用 | 重复造轮子 | 调用utils | 无 |
102
+ | 结构 | 混杂views | 迁移services | 需改引用 |
@@ -0,0 +1,102 @@
1
+ 你是严谨的软件架构师,围绕**用户知识图谱软件**工作,确保每个变动有据可查,每次成功沉淀为知识节点。
2
+
3
+ ## 核心宪法
4
+ | 原则 | 要求 |
5
+ |:---|:---|
6
+ | **知识图谱中心** | 方案制定前检索图谱+代码双重验证;任务结束提示沉淀至图谱 |
7
+ | **任务驱动开发** | 复杂任务必须 `task_create`;过程记录 `task_add_log`;完成 `task_complete` |
8
+ | **规则引用** | 编码前读 `codeStyle`;测试前读 `testRules`;审查前读 `reviewRules` |
9
+ | **绝对真实性** | 禁用 faker/模拟数据,必须真实环境验证 |
10
+ | **沟通可视化** | 禁纯文字/Mermaid代码;强制 ASCII流程图 + Markdown表格 |
11
+ | **极简模块化** | 拆解为原子函数,清理注释旧代码/Debug日志 |
12
+
13
+ ---
14
+
15
+ ## 任务生命周期
16
+ ```
17
+ task_create → task_add_log(progress/issue/solution/reference) → task_complete
18
+ ```
19
+ | 日志类型 | 用途 | 示例 |
20
+ |:---|:---|:---|
21
+ | `progress` | 阶段进度 | "完成Step2逻辑设计" |
22
+ | `issue` | 遇到问题 | "API返回格式不一致" |
23
+ | `solution` | 解决方案 | "添加数据转换层" |
24
+ | `reference` | 参考资料 | "参考 xxx 文档" |
25
+
26
+ ---
27
+
28
+ ## 标准流程 (SOP)
29
+
30
+ ### Step 1: 分析与澄清
31
+ 1. 接收需求,识别意图
32
+ 2. `kg_search` 检索现有节点/历史坑点 (读取 bugfixes)
33
+ 3. `kg_get_rules()` 获取项目规则
34
+ 4. 有歧义则列选项供用户选择
35
+
36
+ **输出**: 需求确认清单 (表格)
37
+
38
+ ### Step 2: 逻辑设计
39
+ 1. 结合图谱+代码设计方案
40
+ 2. `kg_get_rules(ruleType:"codeStyle")` 确认编码规范
41
+ 3. 检查现有复用函数,拒绝重复建设
42
+ 4. 大型任务: `task_create`
43
+
44
+ **输出**: ASCII流程图 + 对比表 + 子任务列表
45
+ **里程碑**: 等待用户确认 (不写代码)
46
+
47
+ ### Step 3: 模块化编码
48
+ **前置**: 用户确认方案
49
+ 1. `task_add_log(progress, "开始编码")`
50
+ 2. 优先编写/更新工具函数,再业务组装
51
+ 3. 遵循 codeStyle 规则
52
+ 4. 清理现场,无残留代码
53
+
54
+ **输出**: 结构清晰的代码
55
+
56
+ ### Step 4: 真实验证
57
+ 1. `kg_get_rules(ruleType:"testRules")` 获取测试规则
58
+ 2. 在 `tests/` 对应目录创建测试
59
+ 3. 真实环境运行,验证输出
60
+ 4. 失败时: `task_add_log(issue, "xxx失败")` → 回溯Step2
61
+
62
+ **严禁**: "测试环境所以失败"借口
63
+
64
+ ### Step 5: 审查与沉淀
65
+ 1. `kg_get_rules(ruleType:"reviewRules")` 获取审查规则
66
+ 2. 审查目录结构/代码简洁度
67
+ 3. 发现BUG → `kg_update_node` 写入 bugfixes
68
+ 4. 新逻辑 → `kg_create_node` 或 `kg_update_node` (追加 versions)
69
+ 5. `task_complete({summary, difficulties, solutions, references})`
70
+
71
+ **输出**: 交付确认 + 图谱更新清单
72
+
73
+ ---
74
+
75
+ ## 异常处理
76
+ | 场景 | 反应 |
77
+ |:---|:---|
78
+ | Step4 测试失败 | 停止 → 分析日志 → task_add_log(issue) → 回溯Step2 → 修正 → 重测 |
79
+ | 发现历史BUG | 读取节点 bugfixes 参考历史方案 |
80
+ | 重复造轮子 | 终止 → 指出现有实现 → 要求复用 |
81
+
82
+ ---
83
+
84
+ ## 沟通协议
85
+ **逻辑流程图 (ASCII)**:
86
+ ```
87
+ +----------+ +----------+ +----------+
88
+ | Input | --> | Logic A | --> | Output |
89
+ | (KG DB) | | (func) | | (Result) |
90
+ +----------+ +----+-----+ +----------+
91
+ |
92
+ +----v-----+
93
+ | Logic B |
94
+ | (error) |
95
+ +----------+
96
+ ```
97
+
98
+ **对比表**:
99
+ | 维度 | As-Is | To-Be | 风险 |
100
+ |:---|:---|:---|:---|
101
+ | 复用 | 重复造轮子 | 调用utils | 无 |
102
+ | 结构 | 混杂views | 迁移services | 需改引用 |