@ppdocs/mcp 3.2.36 → 3.2.38
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 +53 -27
- package/dist/cli.js +2 -1
- package/dist/storage/httpClient.d.ts +24 -10
- package/dist/storage/httpClient.js +50 -63
- package/dist/storage/types.d.ts +42 -0
- package/dist/tools/analyzer.d.ts +1 -1
- package/dist/tools/analyzer.js +8 -7
- package/dist/tools/discussion.js +3 -7
- package/dist/tools/flowchart.js +247 -3
- package/dist/tools/index.d.ts +3 -3
- package/dist/tools/index.js +7 -5
- package/dist/tools/refs.d.ts +2 -0
- package/dist/tools/refs.js +123 -0
- package/dist/tools/tasks.js +2 -2
- package/dist/tools/workflow.d.ts +3 -0
- package/dist/tools/workflow.js +80 -0
- package/dist/utils.d.ts +0 -6
- package/dist/utils.js +0 -44
- package/package.json +1 -1
- package/templates/AGENT.md +3 -2
- package/templates/README.md +2 -2
- package/templates/commands/init.md +3 -3
- package/templates/commands/pp/diagnose.md +6 -6
- package/templates/commands/pp/init.md +9 -18
- package/templates/commands/pp/review.md +9 -10
- package/templates/commands/pp/sync.md +10 -12
- package/templates/cursorrules.md +3 -2
- package/templates/hooks/SystemPrompt.md +16 -16
- package/templates/hooks/hook.py +52 -35
- package/templates/kiro-rules/ppdocs.md +3 -2
- package/dist/tools/rules.d.ts +0 -8
- package/dist/tools/rules.js +0 -121
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
ppdocs MCP 是一个 [Model Context Protocol](https://modelcontextprotocol.io/) 服务器,让 Claude 能够在对话中构建和查询项目知识图谱。
|
|
10
10
|
|
|
11
|
+
当前 MCP 采用 `flowchart-first` 模型:节点、关系、绑定文件、任务关联和节点文档统一收敛到 `kg_flowchart(action:"...")`,不再维护独立的 `kg_doc` / `kg_search` / `kg_create_node` 一组旧接口。
|
|
12
|
+
|
|
11
13
|
```
|
|
12
14
|
┌─────────────┐ MCP ┌─────────────┐ HTTP ┌─────────────┐
|
|
13
15
|
│ Claude AI │ ──────────── │ @ppdocs/mcp │ ────────── │ ppdocs 桌面 │
|
|
@@ -105,28 +107,55 @@ npx @ppdocs/mcp init -p <projectId> -k <key> --codex
|
|
|
105
107
|
|
|
106
108
|
## 工具列表
|
|
107
109
|
|
|
108
|
-
###
|
|
110
|
+
### 核心工具
|
|
109
111
|
|
|
110
112
|
| 工具 | 说明 |
|
|
111
113
|
|------|------|
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
114
|
+
| `kg_init` | 初始化项目连接与上下文 |
|
|
115
|
+
| `kg_status` | 查看项目仪表盘与流程图概况 |
|
|
116
|
+
| `kg_flowchart` | 统一的知识图谱入口,负责查询、更新、关系分析 |
|
|
117
|
+
| `kg_workflow` | Markdown 文档工作流管理 |
|
|
118
|
+
| `kg_task` | 任务管理 |
|
|
119
|
+
| `kg_files` | 项目文件读写/上传下载 |
|
|
120
|
+
| `kg_discuss` | 讨论区 |
|
|
121
|
+
| `kg_meeting` | 多 AI 协作会议 |
|
|
122
|
+
| `code_scan` | 代码扫描 |
|
|
123
|
+
| `code_smart_context` | 获取符号的智能上下文 |
|
|
124
|
+
| `code_full_path` | 获取两个符号之间的全路径 |
|
|
125
|
+
|
|
126
|
+
### `kg_flowchart` actions
|
|
127
|
+
|
|
128
|
+
| action | 说明 |
|
|
129
|
+
|------|------|
|
|
130
|
+
| `list` | 列出所有流程图 |
|
|
131
|
+
| `get` | 获取指定流程图的节点与连线 |
|
|
132
|
+
| `search` | 按关键词搜索节点、节点文档与绑定资源 |
|
|
133
|
+
| `get_relations` | 查看某节点的入边/出边关系 |
|
|
134
|
+
| `find_path` | 查找两个节点之间的有向路径 |
|
|
135
|
+
| `get_node` | 获取节点详情、关联层级、绑定资源与文档 |
|
|
136
|
+
| `update_node` | 更新节点信息并追加节点文档版本 |
|
|
137
|
+
| `delete_node` | 删除节点 |
|
|
138
|
+
| `batch_add` | 批量新增节点与连线 |
|
|
139
|
+
| `bind` / `unbind` | 绑定或解绑文件、目录、文档、任务 |
|
|
140
|
+
| `orphans` | 检查孤立参考文档 |
|
|
141
|
+
| `health` | 查看节点健康度 |
|
|
142
|
+
| `create_chart` | 创建子图并绑定到父节点 |
|
|
143
|
+
| `delete_chart` | 删除子图 |
|
|
144
|
+
|
|
145
|
+
### 常用示例
|
|
120
146
|
|
|
121
|
-
|
|
147
|
+
```bash
|
|
148
|
+
# 搜索相关节点
|
|
149
|
+
kg_flowchart(action:"search", query:"flowchart storage")
|
|
122
150
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
151
|
+
# 查看节点详情
|
|
152
|
+
kg_flowchart(action:"get_node", chartId:"main", nodeId:"n_storage", expand:2, includeDoc:true, includeFiles:true)
|
|
153
|
+
|
|
154
|
+
# 追加节点文档
|
|
155
|
+
kg_flowchart(action:"update_node", chartId:"main", nodeId:"n_storage",
|
|
156
|
+
docSummary:"补充存储层职责",
|
|
157
|
+
docContent:"## 职责\n...\n## 关键流程\n...")
|
|
158
|
+
```
|
|
130
159
|
|
|
131
160
|
---
|
|
132
161
|
|
|
@@ -178,18 +207,15 @@ npx @ppdocs/mcp init -p <projectId> -k <key> --codex
|
|
|
178
207
|
|
|
179
208
|
## 更新日志
|
|
180
209
|
|
|
181
|
-
###
|
|
182
|
-
-
|
|
183
|
-
-
|
|
210
|
+
### v3.2.36
|
|
211
|
+
- 统一为 `flowchart-first` MCP 接口模型
|
|
212
|
+
- `kg_flowchart` 新增 `search` / `get_relations` / `find_path`
|
|
213
|
+
- 文档与模板改为使用 `kg_flowchart(action:"...")`,不再引用旧 `kg_doc` / `kg_search` 等独立接口
|
|
184
214
|
|
|
185
215
|
### v2.5.0
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
|
|
190
|
-
### v2.4.0
|
|
191
|
-
- 🛡️ `kg_lock_node` 只能锁定,解锁需前端手动操作
|
|
192
|
-
- ⚡ 后端自动记录操作日志
|
|
216
|
+
- 新增 CLI init 命令,自动安装工作流模板
|
|
217
|
+
- 支持 Codex 模式 (`--codex`)
|
|
218
|
+
- 构建时自动复制模板
|
|
193
219
|
|
|
194
220
|
### v2.3.0
|
|
195
221
|
- 新增任务管理功能
|
package/dist/cli.js
CHANGED
|
@@ -392,11 +392,12 @@ function generateMcpPermissions() {
|
|
|
392
392
|
'kg_status',
|
|
393
393
|
// 知识管理
|
|
394
394
|
'kg_projects',
|
|
395
|
-
'
|
|
395
|
+
'kg_workflow',
|
|
396
396
|
// 工作流
|
|
397
397
|
'kg_task',
|
|
398
398
|
'kg_files',
|
|
399
399
|
'kg_discuss',
|
|
400
|
+
'kg_ref',
|
|
400
401
|
// 流程图
|
|
401
402
|
'kg_flowchart',
|
|
402
403
|
// 协作
|
|
@@ -4,19 +4,31 @@
|
|
|
4
4
|
*
|
|
5
5
|
* API URL 格式: http://localhost:20099/api/:projectId/:password/...
|
|
6
6
|
*/
|
|
7
|
-
import type { Task, TaskSummary, TaskLogType, TaskExperience, FileInfo,
|
|
7
|
+
import type { Task, TaskSummary, TaskLogType, TaskExperience, FileInfo, WorkflowSummary, WorkflowDoc, WorkflowSelector, Reference } from './types.js';
|
|
8
8
|
export declare class PpdocsApiClient {
|
|
9
9
|
private baseUrl;
|
|
10
10
|
private serverUrl;
|
|
11
11
|
constructor(apiUrl: string);
|
|
12
12
|
private request;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
listWorkflows(scope?: 'all' | 'global' | 'project'): Promise<WorkflowSummary[]>;
|
|
14
|
+
getWorkflow(workflowId: string, scope?: 'all' | 'global' | 'project'): Promise<WorkflowDoc | null>;
|
|
15
|
+
getWorkflowBatch(selectors: WorkflowSelector[]): Promise<WorkflowDoc[]>;
|
|
16
|
+
saveWorkflow(workflowId: string, input: {
|
|
17
|
+
scope: 'global' | 'project';
|
|
18
|
+
title: string;
|
|
19
|
+
description: string;
|
|
20
|
+
system: string;
|
|
21
|
+
keywords: string[];
|
|
22
|
+
minHits: number;
|
|
23
|
+
always: boolean;
|
|
24
|
+
content: string;
|
|
25
|
+
}): Promise<WorkflowDoc>;
|
|
26
|
+
deleteWorkflow(workflowId: string, scope: 'global' | 'project'): Promise<boolean>;
|
|
27
|
+
listReferences(): Promise<Reference[]>;
|
|
28
|
+
getReference(refId: string): Promise<Reference | null>;
|
|
29
|
+
saveReference(reference: Reference): Promise<boolean>;
|
|
30
|
+
deleteReference(refId: string): Promise<boolean>;
|
|
31
|
+
readReferenceFile(path: string): Promise<string>;
|
|
20
32
|
listTasks(status?: 'active' | 'archived'): Promise<TaskSummary[]>;
|
|
21
33
|
getTask(taskId: string, mode?: 'smart' | 'full'): Promise<Task | null>;
|
|
22
34
|
createTask(task: {
|
|
@@ -46,8 +58,6 @@ export declare class PpdocsApiClient {
|
|
|
46
58
|
description: string;
|
|
47
59
|
updatedAt: string;
|
|
48
60
|
}[]>;
|
|
49
|
-
/** 跨项目: 获取规则 */
|
|
50
|
-
crossGetRules(target: string, ruleType: string): Promise<string[]>;
|
|
51
61
|
/** 列出项目文件 */
|
|
52
62
|
listFiles(dir?: string): Promise<FileInfo[]>;
|
|
53
63
|
/** 读取项目文件 */
|
|
@@ -95,6 +105,10 @@ export declare class PpdocsApiClient {
|
|
|
95
105
|
discussionReply(id: string, sender: string, content: string, msgSummary?: string, newSummary?: string): Promise<boolean>;
|
|
96
106
|
/** 完成讨论 (公开路由, 标记为 completed) */
|
|
97
107
|
discussionComplete(id: string): Promise<boolean>;
|
|
108
|
+
/** 归档关闭讨论 (需项目认证) */
|
|
109
|
+
discussionClose(id: string, conclusion: string): Promise<{
|
|
110
|
+
archived_path?: string;
|
|
111
|
+
}>;
|
|
98
112
|
/** 删除讨论 (公开路由) */
|
|
99
113
|
discussionDelete(id: string): Promise<boolean>;
|
|
100
114
|
/** 列出公共文件 */
|
|
@@ -99,75 +99,64 @@ export class PpdocsApiClient {
|
|
|
99
99
|
clearTimeout(timeout);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
// ============
|
|
103
|
-
async
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
return [];
|
|
109
|
-
}
|
|
102
|
+
// ============ 工作流 API ============
|
|
103
|
+
async listWorkflows(scope) {
|
|
104
|
+
const query = scope ? `?scope=${scope}` : '';
|
|
105
|
+
return this.request(`/workflows${query}`);
|
|
110
106
|
}
|
|
111
|
-
async
|
|
107
|
+
async getWorkflow(workflowId, scope) {
|
|
112
108
|
try {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
body: JSON.stringify(rules)
|
|
116
|
-
});
|
|
117
|
-
return true;
|
|
109
|
+
const query = scope ? `?scope=${scope}` : '';
|
|
110
|
+
return await this.request(`/workflows/${encodeURIComponent(workflowId)}${query}`);
|
|
118
111
|
}
|
|
119
112
|
catch {
|
|
120
|
-
return
|
|
113
|
+
return null;
|
|
121
114
|
}
|
|
122
115
|
}
|
|
123
|
-
async
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return {};
|
|
129
|
-
}
|
|
116
|
+
async getWorkflowBatch(selectors) {
|
|
117
|
+
return this.request('/workflows/batch', {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
body: JSON.stringify(selectors),
|
|
120
|
+
});
|
|
130
121
|
}
|
|
131
|
-
async
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
139
|
-
catch {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
122
|
+
async saveWorkflow(workflowId, input) {
|
|
123
|
+
return this.request(`/workflows/${encodeURIComponent(workflowId)}`, {
|
|
124
|
+
method: 'PUT',
|
|
125
|
+
body: JSON.stringify(input),
|
|
126
|
+
});
|
|
142
127
|
}
|
|
143
|
-
async
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
catch {
|
|
148
|
-
return {};
|
|
149
|
-
}
|
|
128
|
+
async deleteWorkflow(workflowId, scope) {
|
|
129
|
+
return this.request(`/workflows/${encodeURIComponent(workflowId)}?scope=${scope}`, {
|
|
130
|
+
method: 'DELETE',
|
|
131
|
+
});
|
|
150
132
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
catch {
|
|
156
|
-
return {};
|
|
157
|
-
}
|
|
133
|
+
// ============ 外部参考 API ============
|
|
134
|
+
async listReferences() {
|
|
135
|
+
return this.request('/refs');
|
|
158
136
|
}
|
|
159
|
-
async
|
|
137
|
+
async getReference(refId) {
|
|
160
138
|
try {
|
|
161
|
-
await this.request(
|
|
162
|
-
method: 'PUT',
|
|
163
|
-
body: JSON.stringify(meta)
|
|
164
|
-
});
|
|
165
|
-
return true;
|
|
139
|
+
return await this.request(`/refs/${encodeURIComponent(refId)}`);
|
|
166
140
|
}
|
|
167
141
|
catch {
|
|
168
|
-
return
|
|
142
|
+
return null;
|
|
169
143
|
}
|
|
170
144
|
}
|
|
145
|
+
async saveReference(reference) {
|
|
146
|
+
await this.request(`/refs/${encodeURIComponent(reference.id)}`, {
|
|
147
|
+
method: 'PUT',
|
|
148
|
+
body: JSON.stringify(reference),
|
|
149
|
+
});
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
async deleteReference(refId) {
|
|
153
|
+
return this.request(`/refs/${encodeURIComponent(refId)}`, {
|
|
154
|
+
method: 'DELETE',
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
async readReferenceFile(path) {
|
|
158
|
+
return this.request(`/refs/files/${cleanPath(path)}`);
|
|
159
|
+
}
|
|
171
160
|
// ============ 任务管理 ============
|
|
172
161
|
async listTasks(status) {
|
|
173
162
|
const query = status ? `?status=${status}` : '';
|
|
@@ -285,15 +274,6 @@ export class PpdocsApiClient {
|
|
|
285
274
|
async crossListProjects() {
|
|
286
275
|
return this.request('/cross/projects');
|
|
287
276
|
}
|
|
288
|
-
/** 跨项目: 获取规则 */
|
|
289
|
-
async crossGetRules(target, ruleType) {
|
|
290
|
-
try {
|
|
291
|
-
return await this.request(`/cross/${encodeURIComponent(target)}/rules/${ruleType}`);
|
|
292
|
-
}
|
|
293
|
-
catch {
|
|
294
|
-
return [];
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
277
|
// ============ 项目文件访问 ============
|
|
298
278
|
/** 列出项目文件 */
|
|
299
279
|
async listFiles(dir) {
|
|
@@ -466,6 +446,13 @@ export class PpdocsApiClient {
|
|
|
466
446
|
method: 'POST',
|
|
467
447
|
});
|
|
468
448
|
}
|
|
449
|
+
/** 归档关闭讨论 (需项目认证) */
|
|
450
|
+
async discussionClose(id, conclusion) {
|
|
451
|
+
return this.request(`/discussions/${encodeURIComponent(id)}/close`, {
|
|
452
|
+
method: 'POST',
|
|
453
|
+
body: JSON.stringify({ conclusion }),
|
|
454
|
+
});
|
|
455
|
+
}
|
|
469
456
|
/** 删除讨论 (公开路由) */
|
|
470
457
|
async discussionDelete(id) {
|
|
471
458
|
return this.publicRequest(`/api/discussions/${encodeURIComponent(id)}`, {
|
package/dist/storage/types.d.ts
CHANGED
|
@@ -4,6 +4,48 @@ export interface RuleMeta {
|
|
|
4
4
|
min_hits: number;
|
|
5
5
|
always?: boolean;
|
|
6
6
|
}
|
|
7
|
+
export interface WorkflowSummary {
|
|
8
|
+
id: string;
|
|
9
|
+
scope: 'global' | 'project';
|
|
10
|
+
title: string;
|
|
11
|
+
description: string;
|
|
12
|
+
system: string;
|
|
13
|
+
keywords: string[];
|
|
14
|
+
minHits: number;
|
|
15
|
+
always: boolean;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
export interface WorkflowDoc extends WorkflowSummary {
|
|
19
|
+
content: string;
|
|
20
|
+
}
|
|
21
|
+
export interface WorkflowSelector {
|
|
22
|
+
id: string;
|
|
23
|
+
scope?: 'global' | 'project';
|
|
24
|
+
}
|
|
25
|
+
export interface ReferenceLink {
|
|
26
|
+
url: string;
|
|
27
|
+
label: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ReferenceFile {
|
|
30
|
+
name: string;
|
|
31
|
+
path: string;
|
|
32
|
+
}
|
|
33
|
+
export interface AdoptedNode {
|
|
34
|
+
chartId: string;
|
|
35
|
+
nodeId: string;
|
|
36
|
+
nodeLabel: string;
|
|
37
|
+
}
|
|
38
|
+
export interface Reference {
|
|
39
|
+
id: string;
|
|
40
|
+
title: string;
|
|
41
|
+
summary: string;
|
|
42
|
+
links: ReferenceLink[];
|
|
43
|
+
files: ReferenceFile[];
|
|
44
|
+
scripts: ReferenceFile[];
|
|
45
|
+
adoptedBy: AdoptedNode[];
|
|
46
|
+
createdAt: string;
|
|
47
|
+
updatedAt: string;
|
|
48
|
+
}
|
|
7
49
|
export interface FileInfo {
|
|
8
50
|
name: string;
|
|
9
51
|
path: string;
|
package/dist/tools/analyzer.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 代码分析引擎工具 (3个)
|
|
3
3
|
* code_scan, code_smart_context, code_full_path
|
|
4
4
|
*
|
|
5
|
-
* code_smart_context: 代码+KG
|
|
5
|
+
* code_smart_context: 代码+KG文档/工作流全关联 (含影响范围)
|
|
6
6
|
* code_full_path: 两点间代码链路+共享KG文档
|
|
7
7
|
*/
|
|
8
8
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
package/dist/tools/analyzer.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 代码分析引擎工具 (3个)
|
|
3
3
|
* code_scan, code_smart_context, code_full_path
|
|
4
4
|
*
|
|
5
|
-
* code_smart_context: 代码+KG
|
|
5
|
+
* code_smart_context: 代码+KG文档/工作流全关联 (含影响范围)
|
|
6
6
|
* code_full_path: 两点间代码链路+共享KG文档
|
|
7
7
|
*/
|
|
8
8
|
import { z } from 'zod';
|
|
@@ -33,7 +33,7 @@ export function registerAnalyzerTools(server, ctx) {
|
|
|
33
33
|
].join('\n'));
|
|
34
34
|
}));
|
|
35
35
|
// ===== code_smart_context: 代码+文档全关联上下文 =====
|
|
36
|
-
server.tool('code_smart_context', '🔍 代码+文档全关联上下文 —
|
|
36
|
+
server.tool('code_smart_context', '🔍 代码+文档全关联上下文 — 输入一个函数名,一次调用返回:代码依赖、关联文档、匹配工作流、活跃任务、影响范围摘要。需先运行 code_scan', {
|
|
37
37
|
projectPath: z.string().optional().describe('项目源码的绝对路径(不传则自动解析)'),
|
|
38
38
|
symbolName: z.string().describe('要查询的符号名称(如"handleLogin", "AuthService")'),
|
|
39
39
|
}, async (args) => safeTool(async () => {
|
|
@@ -75,11 +75,12 @@ export function registerAnalyzerTools(server, ctx) {
|
|
|
75
75
|
}
|
|
76
76
|
lines.push('');
|
|
77
77
|
}
|
|
78
|
-
//
|
|
79
|
-
if (smartCtx.
|
|
80
|
-
lines.push(`###
|
|
81
|
-
for (const
|
|
82
|
-
|
|
78
|
+
// 匹配工作流
|
|
79
|
+
if (smartCtx.matchedWorkflows.length > 0) {
|
|
80
|
+
lines.push(`### 📘 匹配工作流 (${smartCtx.matchedWorkflows.length})`);
|
|
81
|
+
for (const workflow of smartCtx.matchedWorkflows) {
|
|
82
|
+
const desc = workflow.description ? ` — ${workflow.description}` : '';
|
|
83
|
+
lines.push(` [${workflow.scope}/${workflow.system || 'general'}] ${workflow.title}${desc}`);
|
|
83
84
|
}
|
|
84
85
|
lines.push('');
|
|
85
86
|
}
|
package/dist/tools/discussion.js
CHANGED
|
@@ -233,13 +233,9 @@ export function registerDiscussionTools(server, ctx) {
|
|
|
233
233
|
if (brief && !isInitiator(brief, me, myPid)) {
|
|
234
234
|
return wrap(`🔒 无权限: 仅发起人 (${brief.initiator}) 可归档讨论\n你的身份: ${me}`);
|
|
235
235
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
catch { /* 忽略回复失败 */ }
|
|
241
|
-
await client().discussionComplete(decoded.id);
|
|
242
|
-
return wrap(`✅ 讨论已结案 (ID: ${decoded.id})\n📋 ${decoded.conclusion}`);
|
|
236
|
+
const result = await client().discussionClose(decoded.id, decoded.conclusion);
|
|
237
|
+
const archivePath = result?.archived_path ? `\n📦 已归档: ${result.archived_path}` : '';
|
|
238
|
+
return wrap(`✅ 讨论已结案并归档 (ID: ${decoded.id})\n📋 ${decoded.conclusion}${archivePath}`);
|
|
243
239
|
}
|
|
244
240
|
case 'delete': {
|
|
245
241
|
if (!decoded.id)
|