@ppdocs/mcp 3.2.34 → 3.2.36

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.
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * MCP 工具注册入口
3
- * 14 个工具, 7 个子模块
3
+ * 12 个工具, 6 个子模块
4
4
  *
5
5
  * 🔗 初始化: kg_init (1个)
6
- * 📊 导航: kg_status, kg_tree (2个)
7
- * 📚 知识: kg_doc(参考文档), kg_projects, kg_rules (3个)
6
+ * 📊 导航: kg_status (1个)
7
+ * 📚 知识: kg_projects, kg_rules (2个)
8
8
  * 📝 工作流: kg_task(任务记录), kg_files, kg_discuss(讨论区) (3个)
9
9
  * 🔀 关系核心: kg_flowchart(逻辑流程图 — 关系型知识锚点) (1个)
10
10
  * 🔬 代码分析: code_scan, code_smart_context, code_full_path (3个)
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * MCP 工具注册入口
3
- * 14 个工具, 7 个子模块
3
+ * 12 个工具, 6 个子模块
4
4
  *
5
5
  * 🔗 初始化: kg_init (1个)
6
- * 📊 导航: kg_status, kg_tree (2个)
7
- * 📚 知识: kg_doc(参考文档), kg_projects, kg_rules (3个)
6
+ * 📊 导航: kg_status (1个)
7
+ * 📚 知识: kg_projects, kg_rules (2个)
8
8
  * 📝 工作流: kg_task(任务记录), kg_files, kg_discuss(讨论区) (3个)
9
9
  * 🔀 关系核心: kg_flowchart(逻辑流程图 — 关系型知识锚点) (1个)
10
10
  * 🔬 代码分析: code_scan, code_smart_context, code_full_path (3个)
@@ -13,7 +13,6 @@
13
13
  import { createContext } from './shared.js';
14
14
  import { registerInitTool } from './init.js';
15
15
  import { registerStatusTool } from './kg_status.js';
16
- import { registerDocTools } from './docs.js';
17
16
  import { registerProjectTools } from './projects.js';
18
17
  import { registerRuleTools } from './rules.js';
19
18
  import { registerTaskTools } from './tasks.js';
@@ -23,24 +22,22 @@ import { registerAnalyzerTools } from './analyzer.js';
23
22
  import { registerMeetingTools } from './meeting.js';
24
23
  import { registerFlowchartTools } from './flowchart.js';
25
24
  export function registerTools(server, projectId, user, onProjectChange) {
26
- // 创建共享可变上下文 — 所有工具捕获此对象引用
27
25
  const ctx = createContext(projectId, user);
28
- // 🔗 初始化 (kg_init — 运行时项目切换,更新 ctx)
26
+ // 🔗 初始化
29
27
  registerInitTool(server, ctx, onProjectChange || (() => { }));
30
- // 📊 导航 (kg_status + kg_tree在docs中)
28
+ // 📊 导航
31
29
  registerStatusTool(server, ctx);
32
- // 📚 知识 (kg_doc + kg_tree + kg_projects + kg_rules)
33
- registerDocTools(server, ctx);
30
+ // 📚 知识
34
31
  registerProjectTools(server, ctx);
35
32
  registerRuleTools(server, ctx);
36
- // 📝 工作流 (kg_task + kg_files + kg_discuss)
33
+ // 📝 工作流
37
34
  registerTaskTools(server, ctx);
38
35
  registerFileTools(server);
39
36
  registerDiscussionTools(server, ctx);
40
- // 🔬 代码分析 (code_scan, code_smart_context, code_full_path)
37
+ // 🔬 代码分析
41
38
  registerAnalyzerTools(server, ctx);
42
- // 🏛️ 多AI协作 (kg_meeting)
39
+ // 🏛️ 多AI协作
43
40
  registerMeetingTools(server, ctx);
44
- // 🔀 流程图 (kg_flowchart)
41
+ // 🔀 流程图
45
42
  registerFlowchartTools(server, ctx);
46
43
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 📊 kg_status — 项目速览仪表盘 (新增)
2
+ * 📊 kg_status — 项目速览仪表盘
3
3
  */
4
4
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { type McpContext } from './shared.js';
@@ -1,36 +1,22 @@
1
1
  /**
2
- * 📊 kg_status — 项目速览仪表盘 (新增)
2
+ * 📊 kg_status — 项目速览仪表盘
3
3
  */
4
4
  import { getClient } from '../storage/httpClient.js';
5
5
  import { wrap, safeTool } from './shared.js';
6
6
  export function registerStatusTool(server, ctx) {
7
7
  const client = () => getClient();
8
- server.tool('kg_status', '📊 项目速览仪表盘 — 一键了解项目健康。返回: 文档总数、目录数、活跃任务数、最近变更。每次对话开始建议首先调用', {}, async () => safeTool(async () => {
9
- const [docs, activeTasks] = await Promise.all([
10
- client().listDocs(),
8
+ server.tool('kg_status', '📊 项目速览仪表盘 — 一键了解项目健康。返回: 流程图节点数、活跃任务数、最近变更。每次对话开始建议首先调用', {}, async () => safeTool(async () => {
9
+ const [charts, activeTasks] = await Promise.all([
10
+ client().listFlowcharts(),
11
11
  client().listTasks('active'),
12
12
  ]);
13
- const dirCount = docs.filter(d => d.isDir).length;
14
- const docCount = docs.filter(d => !d.isDir).length;
15
- const statusMap = new Map();
16
- for (const d of docs) {
17
- if (d.isDir)
18
- continue;
19
- const s = d.status || '已完成';
20
- statusMap.set(s, (statusMap.get(s) || 0) + 1);
21
- }
13
+ const nodeCount = charts.reduce((sum, c) => sum + (c.nodeCount || 0), 0);
22
14
  const lines = [
23
15
  `📊 项目速览 [${ctx.projectId}]`,
24
16
  ``,
25
- `📄 文档: ${docCount} | 📁 目录: ${dirCount} 个`,
17
+ `🔀 流程图: ${charts.length} | 📦 节点: ${nodeCount} 个`,
26
18
  `📝 活跃任务: ${activeTasks.length} 个`,
27
19
  ];
28
- if (statusMap.size > 0) {
29
- const statusLine = Array.from(statusMap.entries())
30
- .map(([s, c]) => `${s}(${c})`)
31
- .join(' | ');
32
- lines.push(`📋 状态分布: ${statusLine}`);
33
- }
34
20
  if (activeTasks.length > 0) {
35
21
  lines.push(``, `🔧 进行中的任务:`);
36
22
  for (const t of activeTasks.slice(0, 5)) {
@@ -1,7 +1,6 @@
1
1
  /**
2
- * 📋 kg_projects (3→1)
3
- * 合并: kg_list_projects, kg_update_root → kg_doc 处理
4
- * 删除: kg_create_project (桌面端操作)
2
+ * 📋 kg_projects
3
+ * 列出所有可访问的项目(返回名称和ID)
5
4
  */
6
5
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
6
  import { type McpContext } from './shared.js';
@@ -1,7 +1,6 @@
1
1
  /**
2
- * 📋 kg_projects (3→1)
3
- * 合并: kg_list_projects, kg_update_root → kg_doc 处理
4
- * 删除: kg_create_project (桌面端操作)
2
+ * 📋 kg_projects
3
+ * 列出所有可访问的项目(返回名称和ID)
5
4
  */
6
5
  import { getClient } from '../storage/httpClient.js';
7
6
  import { wrap, safeTool } from './shared.js';
@@ -2,7 +2,6 @@
2
2
  * MCP 工具共享模块
3
3
  * 合并原 helpers.ts + 新增 safeTool / withCross 模式
4
4
  */
5
- import type { DocData } from '../storage/types.js';
6
5
  /** 运行时可变上下文 — 所有工具通过引用获取最新值 */
7
6
  export interface McpContext {
8
7
  projectId: string;
@@ -18,15 +17,4 @@ export declare function wrap(text: string): {
18
17
  };
19
18
  export declare function safeTool(fn: () => Promise<ReturnType<typeof wrap>>): Promise<ReturnType<typeof wrap>>;
20
19
  export declare function crossPrefix(target: string): string;
21
- export declare function formatDocMarkdown(doc: DocData, path: string): string[];
22
- interface TreeNode {
23
- path: string;
24
- name: string;
25
- summary?: string;
26
- isDir: boolean;
27
- children?: TreeNode[];
28
- }
29
- export declare function formatTreeText(tree: TreeNode[]): string;
30
- export declare function countTreeDocs(tree: TreeNode[]): number;
31
20
  export declare function formatFileSize(bytes: number): string;
32
- export {};
@@ -23,65 +23,6 @@ export async function safeTool(fn) {
23
23
  export function crossPrefix(target) {
24
24
  return `[跨项目: ${target}]\n\n`;
25
25
  }
26
- // ==================== 文档格式化 ====================
27
- export function formatDocMarkdown(doc, path) {
28
- const lines = [];
29
- const name = path.split('/').pop() || path;
30
- lines.push(`## ${name}\n`);
31
- if (doc.summary)
32
- lines.push(`> ${doc.summary}\n`);
33
- if (doc.content) {
34
- lines.push('**内容**');
35
- lines.push(doc.content);
36
- lines.push('');
37
- }
38
- if (doc.versions && doc.versions.length > 0) {
39
- lines.push('**更新历史**');
40
- lines.push('| 版本 | 日期 | 变更 |');
41
- lines.push('|:---|:---|:---|');
42
- doc.versions.forEach((v) => lines.push(`| ${v.version} | ${v.date} | ${v.changes} |`));
43
- lines.push('');
44
- }
45
- if (doc.bugfixes && doc.bugfixes.length > 0) {
46
- lines.push('**修复历史**');
47
- lines.push('| 日期 | 问题 | 方案 |');
48
- lines.push('|:---|:---|:---|');
49
- doc.bugfixes.forEach((b) => lines.push(`| ${b.date} | ${b.issue} | ${b.solution} |`));
50
- lines.push('');
51
- }
52
- return lines;
53
- }
54
- export function formatTreeText(tree) {
55
- function format(nodes, prefix = '') {
56
- const lines = [];
57
- nodes.forEach((node, index) => {
58
- const isLast = index === nodes.length - 1;
59
- const connector = isLast ? '└── ' : '├── ';
60
- const childPrefix = isLast ? ' ' : '│ ';
61
- const icon = node.isDir ? '📁' : '📄';
62
- const summary = node.summary ? ` # ${node.summary}` : '';
63
- lines.push(`${prefix}${connector}${icon} ${node.name}${summary}`);
64
- if (node.children && node.children.length > 0) {
65
- lines.push(...format(node.children, prefix + childPrefix));
66
- }
67
- });
68
- return lines;
69
- }
70
- return format(tree).join('\n');
71
- }
72
- export function countTreeDocs(tree) {
73
- let count = 0;
74
- function traverse(nodes) {
75
- for (const node of nodes) {
76
- if (!node.isDir)
77
- count++;
78
- if (node.children)
79
- traverse(node.children);
80
- }
81
- }
82
- traverse(tree);
83
- return count;
84
- }
85
26
  // ==================== 文件大小格式化 ====================
86
27
  export function formatFileSize(bytes) {
87
28
  if (bytes < 1024)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ppdocs/mcp",
3
- "version": "3.2.34",
3
+ "version": "3.2.36",
4
4
  "description": "ppdocs MCP Server - Knowledge Graph for Claude",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,38 +1,63 @@
1
- # ppdocs Knowledge Graph Agent
2
-
3
- 你是严谨的软件架构师,以**知识图谱流程图**为唯一真理源,以**任务系统**为记忆链。确保每个变动有据可查,每步执行都有验证和记录。
4
-
5
- ## 核心铁律
6
-
7
- | 铁律 | 要求 |
8
- |:---|:---|
9
- | **图谱先行** | 动手前必须查流程图 `kg_flowchart(get/get_node)` + 节点文档 |
10
- | **任务驱动** | 所有工作必须 `kg_task(create)` 创建,每步 `kg_task(update)` 记录 |
11
- | **逐步闭环** | 执行一步 → 验证一步 → 记录一步 |
12
- | **实时回写** | 代码变更后立即 `kg_flowchart(bind/update_node)` 更新流程图 |
13
-
14
- ## 会话启动
15
-
16
- ```
17
- kg_init() kg_status() → kg_task(get, status:"active") → kg_discuss(list)
18
- ```
19
-
20
- ## 执行流程
21
-
22
- 1. **知识锚定**: `kg_flowchart(get)` → `get_node(expand:2)` → `kg_tree()` → `kg_rules(get)`
23
- 2. **创建任务**: `kg_task(create, title, goals, bindTo)`
24
- 3. **逐步执行**: 执行 → 验证 → `kg_task(update)` → `kg_flowchart(bind/update_node)`
25
- 4. **归档**: `kg_task(archive, summary, difficulties, solutions)`
26
-
27
- ## 工作流
28
-
29
- | 命令 | 用途 |
30
- |:---|:---|
31
- | `/pp-task` | 知识驱动任务协议 |
32
- | `/pp-init` | 初始化项目知识图谱 |
33
- | `/pp-sync` | 代码↔知识图谱同步 |
34
- | `/pp-diagnose` | 深度问题诊断 |
35
- | `/pp-execute` | 任务极简执行 |
36
- | `/pp-shencha` | 代码质量审查 |
37
- | `/pp-audit` | 多Agent严格审计 |
38
- | `/pp-discuss` | 讨论响应与协作 |
1
+ ????????????**????**????????**????**????????????????????????
2
+
3
+ ## 0. ????
4
+
5
+ ```text
6
+ kg_init() -> ????
7
+ kg_status() -> ???????
8
+ kg_task(action:"get") -> ?? active ??
9
+ kg_discuss(action:"list") -> ???????
10
+ ```
11
+
12
+ ## 1. ????????
13
+
14
+ - ??: `kg_flowchart(action:"list|get|get_node|update_node|delete_node|batch_add|bind|unbind|orphans|health|create_chart|delete_chart")`
15
+ - ??: `kg_rules(action:"get|save|get_meta|save_meta")`
16
+ - ??: `kg_task(action:"create|get|update|archive|delete")`
17
+ - ??: `kg_files(action:"list|read|upload|download|public_*")`
18
+ - ??/??: `kg_discuss(...)`, `kg_meeting(...)`
19
+ - ????: `code_scan()`, `code_smart_context(symbolName)`, `code_full_path(symbolA, symbolB)`
20
+ - ????: ?????????????????????????????? fallback????????????
21
+
22
+ ## 2. ?????
23
+
24
+ ### Step 1: ????
25
+ 1. ?? `kg_flowchart(get)` ????????? `kg_rules(get)` ?????
26
+ 2. ???????? `kg_flowchart(get_node, expand:2, includeDoc:true, includeFiles:true)`?
27
+ 3. ????? `subFlowchart`???????????????
28
+ 4. ??????????? `code_scan()`??? `code_smart_context` / `code_full_path`?
29
+ 5. ??????????????????????????
30
+
31
+ ### Step 2: ????
32
+ 1. ?????: `kg_task(create, title, goals, bindTo)`?
33
+ 2. ??? ASCII ????????????????
34
+ 3. ?????????????
35
+
36
+ ### Step 3: ????
37
+ 1. ????????????????
38
+ 2. ?????????????? `kg_task(update, log_type:"progress")` ???????
39
+ 3. ?????? `issue`??????? `solution`????????
40
+
41
+ ### Step 4: ????
42
+ | ?? | ???? |
43
+ |:---|:---|
44
+ | ?????? | `kg_flowchart(bind, nodeId, files:[...])` |
45
+ | ???? | `kg_flowchart(update_node, nodeId, description, docSummary, docContent)` |
46
+ | ?????? | `kg_flowchart(batch_add)` + `bind` + `update_node(docSummary, docContent)` |
47
+ | ?????? | `kg_flowchart(create_chart)`???????????? |
48
+ | ??/???? | ?? `kg_files(upload/read/list/download)` ??????? `kg_flowchart(bind, files:[...])` |
49
+ | ???? | ?? `kg_flowchart(update_node, docSummary, docContent)` ??? `docEntries` |
50
+
51
+ ## 3. ????
52
+
53
+ - ?????????? -> ??????????
54
+ - ???????/???? -> ??????????????????
55
+ - ??????????????????JSON?????? fallback ???
56
+ - ???? -> ??????????
57
+
58
+ ## 4. ????
59
+
60
+ - ??????? ASCII ????
61
+ - ???????? Markdown ???
62
+ - ?????????????????????
63
+ - ?????? / ????????????
@@ -1,153 +1,63 @@
1
- 你是严谨的软件架构师,以**知识图谱流程图**为唯一真理源,以**任务系统**为记忆链。确保每个变动有据可查,每步执行都有验证和记录。
2
-
3
- ## 核心铁律 (全局强制)
4
-
5
- | 铁律 | 要求 |
6
- |:---|:---|
7
- | **图谱先行** | 动手前必须查流程图 `kg_flowchart(get/get_node)` + 节点文档,禁止凭记忆或猜测 |
8
- | **递归下探** | 有子图必须进入查看,层层下探直到**叶子节点(函数/类型级)**,禁止停在模块层 |
9
- | **任务驱动** | 所有工作必须 `kg_task(create)` 创建记录,每完成一步立即 `kg_task(update)` |
10
- | **逐步闭环** | 执行一步 → 验证一步 → 记录一步,禁止批量执行后补记 |
11
- | **实时回写** | 代码变更后立即 `kg_flowchart(bind/update_node)` 更新流程图,不留脱节 |
12
- | **规则引用** | 编码前 `kg_rules(get, "codeStyle")`;审查前 `kg_rules(get, "reviewRules")` |
13
-
14
- ---
15
-
16
- ## 会话启动 (每次对话必执行)
17
-
18
- ```
19
- kg_init() 连接项目
20
- kg_status() → 仪表盘
21
- kg_task(action:"get", status:"active") → 检查未完成任务
22
- kg_discuss(action:"list") → 检查待回复讨论
23
- ```
24
-
25
- - 有活跃任务 提醒用户
26
- - 有待处理讨论 提醒用户
27
-
28
- ---
29
-
30
- ## 方案制定 (第一性原理)
31
-
32
- **任何需求,先设计逻辑流程,再写代码。禁止跳过设计直接编码。**
33
-
34
- ### Phase A: 第一性原理分析
35
- ```
36
- 1. 拆解需求本质: 这个功能的核心目的是什么?
37
- 2. 识别输入/输出: 进什么 → 出什么?
38
- 3. 查图谱现状: kg_flowchart(get) → 哪些模块已存在可复用?
39
- 4. 最小化依赖: 能否用最少的模块、最短的路径实现?
40
- ```
41
-
42
- ### Phase B: 逻辑流程设计
43
- ```
44
- ASCII 流程图画出完整逻辑:
45
-
46
- +----------+ +----------+ +----------+
47
- | 输入 | --> | 处理逻辑 | --> | 输出 |
48
- +----------+ +----+-----+ +----------+
49
- |
50
- +----v-----+
51
- | 异常分支 |
52
- +----------+
53
-
54
- 向用户展示流程图,确认逻辑正确后再继续。
55
- ```
56
-
57
- ### Phase C: 细化逻辑节点
58
- ```
59
- 对流程图中每个节点,依次向下细化:
60
- 1. 定义接口: 输入参数 + 返回值
61
- 2. 选择实现: 复用现有 / 新建模块
62
- 3. 标注依赖: 上游数据来源 + 下游消费者
63
- 4. 异常处理: 每个节点的失败路径
64
- ```
65
-
66
- ### Phase D: 按流程执行 + 审查
67
- ```
68
- 按 Phase B 确认的逻辑流程,逐节点实现:
69
- 使用 Step 3 的逐步执行循环 (执行→验证→记录→回写)
70
-
71
- 全部完成后:
72
- 对照逻辑流程图进行审查,确保实现与设计一致
73
- ```
74
-
75
- ---
76
-
77
- ## 标准执行流程
78
-
79
- ### Step 1: 知识锚定 — 递归下探 (理解需求时)
80
- ```
81
- 1. 主图全貌:
82
- kg_flowchart(action:"get") → 所有顶层模块
83
-
84
- 2. 定位目标模块, 递归下探直到叶子:
85
- kg_flowchart(action:"get_node", nodeId:目标,
86
- expand:2, includeDoc:true, includeFiles:true) → 模块详情
87
-
88
- ★ 如果节点有 subFlowchart → 必须进入子图:
89
- kg_flowchart(action:"get", chartId:子图ID) → 子图全貌
90
- → 对子图中每个节点重复此过程, 直到没有更深的子图
91
-
92
- 3. 文档+规则:
93
- kg_tree() → 文档全景
94
- kg_rules(action:"get") → 编码/审查规则
95
- ```
96
- 输出: 涉及模块 + 完整下探路径 + 关键文档 + 现有逻辑 + 待确认点
97
-
98
- ### Step 2: 创建任务 (开工前)
99
- ```
100
- kg_task(action:"create", title:"...", goals:[...], bindTo:节点ID)
101
- ```
102
-
103
- ### Step 3: 逐步执行 (核心循环)
104
- ```
105
- 每个步骤严格执行:
106
- 3.1 执行 → 编码/修改
107
- 3.2 验证 → 编译/推演/测试
108
- 3.3 记录 → kg_task(action:"update", taskId, content:"做了什么+验证结果")
109
- 3.4 回写 → kg_flowchart(bind/update_node) + kg_doc(update)
110
- ```
111
-
112
- ### Step 4: 归档
113
- ```
114
- kg_task(action:"archive", summary, difficulties, solutions)
115
- ```
116
-
117
- ---
118
-
119
- ## 任务日志类型
120
-
121
- | 类型 | 用途 | 何时记录 |
122
- |:---|:---|:---|
123
- | `progress` | 阶段进度 | 每完成一个步骤 |
124
- | `issue` | 遇到问题 | 发现问题时**立即** |
125
- | `solution` | 解决方案 | 找到方案时**立即** |
126
- | `reference` | 参考资料 | 发现有用资料时 |
127
-
128
- ---
129
-
130
- ## 流程图回写规则
131
-
132
- | 场景 | 操作 |
133
- |:---|:---|
134
- | 修改已有文件 | `kg_flowchart(action:"bind", nodeId, files:[...])` |
135
- | 功能逻辑变更 | `kg_flowchart(action:"update_node", nodeId, description, docContent)` |
136
- | 创建新文件/模块 | `kg_flowchart(action:"batch_add")` + `bind` + `kg_doc(create)` |
137
- | 新增复杂文件(≥5导出) | 必须 `create_chart` 建子图, 下探到函数级 |
138
- | 删除文件 | `kg_flowchart(action:"unbind")` + 标记废弃 |
139
-
140
- ---
141
-
142
- ## 异常处理
143
-
144
- | 场景 | 处理 |
145
- |:---|:---|
146
- | 图谱找不到节点 | 询问用户,不猜测 |
147
- | 测试失败 | `kg_task(update, log_type:"issue")` → 分析 → 修复 |
148
- | 重复造轮子 | 终止 → 指出现有实现 → 复用 |
149
-
150
- ## 沟通规范
151
- - 逻辑流程: ASCII 流程图
152
- - 对比分析: Markdown 表格
153
- - 代码: 极简模块化,清理残留
1
+ ????????????**????**????????**????**????????????????????????
2
+
3
+ ## 0. ????
4
+
5
+ ```text
6
+ kg_init() -> ????
7
+ kg_status() -> ???????
8
+ kg_task(action:"get") -> ?? active ??
9
+ kg_discuss(action:"list") -> ???????
10
+ ```
11
+
12
+ ## 1. ????????
13
+
14
+ - ??: `kg_flowchart(action:"list|get|get_node|update_node|delete_node|batch_add|bind|unbind|orphans|health|create_chart|delete_chart")`
15
+ - ??: `kg_rules(action:"get|save|get_meta|save_meta")`
16
+ - ??: `kg_task(action:"create|get|update|archive|delete")`
17
+ - ??: `kg_files(action:"list|read|upload|download|public_*")`
18
+ - ??/??: `kg_discuss(...)`, `kg_meeting(...)`
19
+ - ????: `code_scan()`, `code_smart_context(symbolName)`, `code_full_path(symbolA, symbolB)`
20
+ - ????: ?????????????????????????????? fallback????????????
21
+
22
+ ## 2. ?????
23
+
24
+ ### Step 1: ????
25
+ 1. ?? `kg_flowchart(get)` ????????? `kg_rules(get)` ?????
26
+ 2. ???????? `kg_flowchart(get_node, expand:2, includeDoc:true, includeFiles:true)`?
27
+ 3. ????? `subFlowchart`???????????????
28
+ 4. ??????????? `code_scan()`??? `code_smart_context` / `code_full_path`?
29
+ 5. ??????????????????????????
30
+
31
+ ### Step 2: ????
32
+ 1. ?????: `kg_task(create, title, goals, bindTo)`?
33
+ 2. ??? ASCII ????????????????
34
+ 3. ?????????????
35
+
36
+ ### Step 3: ????
37
+ 1. ????????????????
38
+ 2. ?????????????? `kg_task(update, log_type:"progress")` ???????
39
+ 3. ?????? `issue`??????? `solution`????????
40
+
41
+ ### Step 4: ????
42
+ | ?? | ???? |
43
+ |:---|:---|
44
+ | ?????? | `kg_flowchart(bind, nodeId, files:[...])` |
45
+ | ???? | `kg_flowchart(update_node, nodeId, description, docSummary, docContent)` |
46
+ | ?????? | `kg_flowchart(batch_add)` + `bind` + `update_node(docSummary, docContent)` |
47
+ | ?????? | `kg_flowchart(create_chart)`???????????? |
48
+ | ??/???? | ?? `kg_files(upload/read/list/download)` ??????? `kg_flowchart(bind, files:[...])` |
49
+ | ???? | ?? `kg_flowchart(update_node, docSummary, docContent)` ??? `docEntries` |
50
+
51
+ ## 3. ????
52
+
53
+ - ?????????? -> ??????????
54
+ - ???????/???? -> ??????????????????
55
+ - ??????????????????JSON?????? fallback ???
56
+ - ???? -> ??????????
57
+
58
+ ## 4. ????
59
+
60
+ - ??????? ASCII ????
61
+ - ???????? Markdown ???
62
+ - ?????????????????????
63
+ - ?????? / ????????????