aifastdb-devplan 1.0.0 → 1.0.2
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 +669 -40
- package/dist/dev-plan-document-store.d.ts +309 -0
- package/dist/dev-plan-document-store.d.ts.map +1 -0
- package/dist/dev-plan-document-store.js +1543 -0
- package/dist/dev-plan-document-store.js.map +1 -0
- package/dist/dev-plan-factory.d.ts +49 -0
- package/dist/dev-plan-factory.d.ts.map +1 -0
- package/dist/dev-plan-factory.js +218 -0
- package/dist/dev-plan-factory.js.map +1 -0
- package/dist/dev-plan-graph-store.d.ts +114 -0
- package/dist/dev-plan-graph-store.d.ts.map +1 -0
- package/dist/dev-plan-graph-store.js +1073 -0
- package/dist/dev-plan-graph-store.js.map +1 -0
- package/dist/dev-plan-interface.d.ts +165 -0
- package/dist/dev-plan-interface.d.ts.map +1 -0
- package/dist/dev-plan-interface.js +10 -0
- package/dist/dev-plan-interface.js.map +1 -0
- package/dist/dev-plan-migrate.d.ts +52 -0
- package/dist/dev-plan-migrate.d.ts.map +1 -0
- package/dist/dev-plan-migrate.js +407 -0
- package/dist/dev-plan-migrate.js.map +1 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -10
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/index.d.ts +1 -0
- package/dist/mcp-server/index.d.ts.map +1 -1
- package/dist/mcp-server/index.js +304 -92
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/types.d.ts +375 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +37 -0
- package/dist/types.js.map +1 -0
- package/dist/visualize/server.d.ts +18 -0
- package/dist/visualize/server.d.ts.map +1 -0
- package/dist/visualize/server.js +229 -0
- package/dist/visualize/server.js.map +1 -0
- package/dist/visualize/template.d.ts +8 -0
- package/dist/visualize/template.d.ts.map +1 -0
- package/dist/visualize/template.js +528 -0
- package/dist/visualize/template.js.map +1 -0
- package/package.json +14 -4
package/dist/mcp-server/index.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* - devplan_list_modules: List all feature modules
|
|
23
23
|
* - devplan_get_module: Get module details with associated tasks and docs
|
|
24
24
|
* - devplan_update_module: Update module info
|
|
25
|
+
* - devplan_start_visual: Start the graph visualization HTTP server
|
|
25
26
|
*/
|
|
26
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
28
|
// @ts-ignore - MCP SDK types will be available after npm install
|
|
@@ -30,16 +31,26 @@ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
|
30
31
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
31
32
|
// @ts-ignore - MCP SDK types will be available after npm install
|
|
32
33
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
33
|
-
const
|
|
34
|
+
const dev_plan_factory_1 = require("../dev-plan-factory");
|
|
35
|
+
const dev_plan_migrate_1 = require("../dev-plan-migrate");
|
|
36
|
+
const types_1 = require("../types");
|
|
34
37
|
// ============================================================================
|
|
35
38
|
// DevPlan Store Cache
|
|
36
39
|
// ============================================================================
|
|
37
40
|
const devPlanCache = new Map();
|
|
38
|
-
function getDevPlan(projectName) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
function getDevPlan(projectName, engine) {
|
|
42
|
+
const cacheKey = projectName;
|
|
43
|
+
if (engine) {
|
|
44
|
+
// 显式指定引擎时,清除缓存以使用新引擎
|
|
45
|
+
devPlanCache.delete(cacheKey);
|
|
46
|
+
const plan = (0, dev_plan_factory_1.createDevPlan)(projectName, undefined, engine);
|
|
47
|
+
devPlanCache.set(cacheKey, plan);
|
|
48
|
+
return plan;
|
|
41
49
|
}
|
|
42
|
-
|
|
50
|
+
if (!devPlanCache.has(cacheKey)) {
|
|
51
|
+
devPlanCache.set(cacheKey, (0, dev_plan_factory_1.createDevPlan)(projectName));
|
|
52
|
+
}
|
|
53
|
+
return devPlanCache.get(cacheKey);
|
|
43
54
|
}
|
|
44
55
|
// ============================================================================
|
|
45
56
|
// Tool Definitions
|
|
@@ -47,51 +58,51 @@ function getDevPlan(projectName) {
|
|
|
47
58
|
const TOOLS = [
|
|
48
59
|
{
|
|
49
60
|
name: 'devplan_init',
|
|
50
|
-
description: 'Initialize a development plan for a project. Creates an empty plan structure. Also lists existing plans if no projectName is given
|
|
61
|
+
description: 'Initialize a development plan for a project. Creates an empty plan structure. Also lists existing plans if no projectName is given.\n初始化项目的开发计划。创建空的计划结构。如果不提供 projectName 则列出已有的计划。',
|
|
51
62
|
inputSchema: {
|
|
52
63
|
type: 'object',
|
|
53
64
|
properties: {
|
|
54
65
|
projectName: {
|
|
55
66
|
type: 'string',
|
|
56
|
-
description: 'Project name (e.g., "federation-db", "aidb-viewer"). Omit to list existing plans
|
|
67
|
+
description: 'Project name (e.g., "federation-db", "aidb-viewer"). Omit to list existing plans.\n项目名称(如 "federation-db")。省略则列出已有计划。',
|
|
57
68
|
},
|
|
58
69
|
},
|
|
59
70
|
},
|
|
60
71
|
},
|
|
61
72
|
{
|
|
62
73
|
name: 'devplan_save_section',
|
|
63
|
-
description: 'Save or update a document section in the dev plan. Sections are typed: overview, core_concepts, api_design, file_structure, config, examples, technical_notes, api_endpoints, milestones, changelog, custom. technical_notes and custom support subSection for multiple sub-documents
|
|
74
|
+
description: 'Save or update a document section in the dev plan. Sections are typed: overview, core_concepts, api_design, file_structure, config, examples, technical_notes, api_endpoints, milestones, changelog, custom. technical_notes and custom support subSection for multiple sub-documents.\n保存或更新开发计划中的文档片段。支持 11 种标准类型。technical_notes 和 custom 支持通过 subSection 存储多个子文档。',
|
|
64
75
|
inputSchema: {
|
|
65
76
|
type: 'object',
|
|
66
77
|
properties: {
|
|
67
78
|
projectName: {
|
|
68
79
|
type: 'string',
|
|
69
|
-
description: 'Project name',
|
|
80
|
+
description: 'Project name\n项目名称',
|
|
70
81
|
},
|
|
71
82
|
section: {
|
|
72
83
|
type: 'string',
|
|
73
84
|
enum: ['overview', 'core_concepts', 'api_design', 'file_structure', 'config', 'examples', 'technical_notes', 'api_endpoints', 'milestones', 'changelog', 'custom'],
|
|
74
|
-
description: 'Document section type',
|
|
85
|
+
description: 'Document section type\n文档片段类型',
|
|
75
86
|
},
|
|
76
87
|
title: {
|
|
77
88
|
type: 'string',
|
|
78
|
-
description: 'Section title (e.g., "概述 - 背景与目标"
|
|
89
|
+
description: 'Section title (e.g., "Overview - Background")\n片段标题(如 "概述 - 背景与目标")',
|
|
79
90
|
},
|
|
80
91
|
content: {
|
|
81
92
|
type: 'string',
|
|
82
|
-
description: 'Markdown content for this section',
|
|
93
|
+
description: 'Markdown content for this section\n该片段的 Markdown 内容',
|
|
83
94
|
},
|
|
84
95
|
version: {
|
|
85
96
|
type: 'string',
|
|
86
|
-
description: 'Optional version string (default: "1.0.0")',
|
|
97
|
+
description: 'Optional version string (default: "1.0.0")\n可选版本号(默认 "1.0.0")',
|
|
87
98
|
},
|
|
88
99
|
subSection: {
|
|
89
100
|
type: 'string',
|
|
90
|
-
description: 'Optional sub-section name for technical_notes/custom (e.g., "security", "resilience")',
|
|
101
|
+
description: 'Optional sub-section name for technical_notes/custom (e.g., "security", "resilience")\n可选子片段名称,用于 technical_notes/custom(如 "security")',
|
|
91
102
|
},
|
|
92
103
|
moduleId: {
|
|
93
104
|
type: 'string',
|
|
94
|
-
description: 'Optional: Associate with a feature module',
|
|
105
|
+
description: 'Optional: Associate with a feature module\n可选:关联到功能模块',
|
|
95
106
|
},
|
|
96
107
|
},
|
|
97
108
|
required: ['projectName', 'section', 'title', 'content'],
|
|
@@ -99,22 +110,22 @@ const TOOLS = [
|
|
|
99
110
|
},
|
|
100
111
|
{
|
|
101
112
|
name: 'devplan_get_section',
|
|
102
|
-
description: 'Read a specific document section from the dev plan
|
|
113
|
+
description: 'Read a specific document section from the dev plan.\n读取开发计划中的指定文档片段。',
|
|
103
114
|
inputSchema: {
|
|
104
115
|
type: 'object',
|
|
105
116
|
properties: {
|
|
106
117
|
projectName: {
|
|
107
118
|
type: 'string',
|
|
108
|
-
description: 'Project name',
|
|
119
|
+
description: 'Project name\n项目名称',
|
|
109
120
|
},
|
|
110
121
|
section: {
|
|
111
122
|
type: 'string',
|
|
112
123
|
enum: ['overview', 'core_concepts', 'api_design', 'file_structure', 'config', 'examples', 'technical_notes', 'api_endpoints', 'milestones', 'changelog', 'custom'],
|
|
113
|
-
description: 'Document section type',
|
|
124
|
+
description: 'Document section type\n文档片段类型',
|
|
114
125
|
},
|
|
115
126
|
subSection: {
|
|
116
127
|
type: 'string',
|
|
117
|
-
description: 'Optional sub-section name',
|
|
128
|
+
description: 'Optional sub-section name\n可选子片段名称',
|
|
118
129
|
},
|
|
119
130
|
},
|
|
120
131
|
required: ['projectName', 'section'],
|
|
@@ -122,13 +133,13 @@ const TOOLS = [
|
|
|
122
133
|
},
|
|
123
134
|
{
|
|
124
135
|
name: 'devplan_list_sections',
|
|
125
|
-
description: 'List all document sections in the dev plan for a project
|
|
136
|
+
description: 'List all document sections in the dev plan for a project.\n列出项目开发计划中的所有文档片段。',
|
|
126
137
|
inputSchema: {
|
|
127
138
|
type: 'object',
|
|
128
139
|
properties: {
|
|
129
140
|
projectName: {
|
|
130
141
|
type: 'string',
|
|
131
|
-
description: 'Project name',
|
|
142
|
+
description: 'Project name\n项目名称',
|
|
132
143
|
},
|
|
133
144
|
},
|
|
134
145
|
required: ['projectName'],
|
|
@@ -136,38 +147,38 @@ const TOOLS = [
|
|
|
136
147
|
},
|
|
137
148
|
{
|
|
138
149
|
name: 'devplan_create_main_task',
|
|
139
|
-
description: 'Create a main task (development phase) in the dev plan. A main task groups multiple sub-tasks
|
|
150
|
+
description: 'Create a main task (development phase) in the dev plan. A main task groups multiple sub-tasks.\n在开发计划中创建主任务(开发阶段)。一个主任务下包含多个子任务。',
|
|
140
151
|
inputSchema: {
|
|
141
152
|
type: 'object',
|
|
142
153
|
properties: {
|
|
143
154
|
projectName: {
|
|
144
155
|
type: 'string',
|
|
145
|
-
description: 'Project name',
|
|
156
|
+
description: 'Project name\n项目名称',
|
|
146
157
|
},
|
|
147
158
|
taskId: {
|
|
148
159
|
type: 'string',
|
|
149
|
-
description: 'Main task ID (e.g., "phase-7", "phase-14B")',
|
|
160
|
+
description: 'Main task ID (e.g., "phase-7", "phase-14B")\n主任务 ID(如 "phase-7")',
|
|
150
161
|
},
|
|
151
162
|
title: {
|
|
152
163
|
type: 'string',
|
|
153
|
-
description: 'Task title (e.g., "阶段七:Store Trait 与适配器"
|
|
164
|
+
description: 'Task title (e.g., "Phase 7: Store Trait & Adapters")\n任务标题(如 "阶段七:Store Trait 与适配器")',
|
|
154
165
|
},
|
|
155
166
|
priority: {
|
|
156
167
|
type: 'string',
|
|
157
168
|
enum: ['P0', 'P1', 'P2'],
|
|
158
|
-
description: 'Priority level',
|
|
169
|
+
description: 'Priority level\n优先级',
|
|
159
170
|
},
|
|
160
171
|
description: {
|
|
161
172
|
type: 'string',
|
|
162
|
-
description: 'Optional task description',
|
|
173
|
+
description: 'Optional task description\n可选任务描述',
|
|
163
174
|
},
|
|
164
175
|
estimatedHours: {
|
|
165
176
|
type: 'number',
|
|
166
|
-
description: 'Optional estimated hours',
|
|
177
|
+
description: 'Optional estimated hours\n可选预估工时',
|
|
167
178
|
},
|
|
168
179
|
moduleId: {
|
|
169
180
|
type: 'string',
|
|
170
|
-
description: 'Optional: Associate with a feature module',
|
|
181
|
+
description: 'Optional: Associate with a feature module\n可选:关联到功能模块',
|
|
171
182
|
},
|
|
172
183
|
},
|
|
173
184
|
required: ['projectName', 'taskId', 'title', 'priority'],
|
|
@@ -175,33 +186,33 @@ const TOOLS = [
|
|
|
175
186
|
},
|
|
176
187
|
{
|
|
177
188
|
name: 'devplan_add_sub_task',
|
|
178
|
-
description: 'Add a sub-task under a main task. Sub-tasks correspond to Cursor TodoList items
|
|
189
|
+
description: 'Add a sub-task under a main task. Sub-tasks correspond to Cursor TodoList items.\n在主任务下添加子任务。子任务对应 Cursor 的 TodoList 条目。',
|
|
179
190
|
inputSchema: {
|
|
180
191
|
type: 'object',
|
|
181
192
|
properties: {
|
|
182
193
|
projectName: {
|
|
183
194
|
type: 'string',
|
|
184
|
-
description: 'Project name',
|
|
195
|
+
description: 'Project name\n项目名称',
|
|
185
196
|
},
|
|
186
197
|
taskId: {
|
|
187
198
|
type: 'string',
|
|
188
|
-
description: 'Sub-task ID (e.g., "T7.2", "T14.8")',
|
|
199
|
+
description: 'Sub-task ID (e.g., "T7.2", "T14.8")\n子任务 ID(如 "T7.2")',
|
|
189
200
|
},
|
|
190
201
|
parentTaskId: {
|
|
191
202
|
type: 'string',
|
|
192
|
-
description: 'Parent main task ID (e.g., "phase-7")',
|
|
203
|
+
description: 'Parent main task ID (e.g., "phase-7")\n所属主任务 ID(如 "phase-7")',
|
|
193
204
|
},
|
|
194
205
|
title: {
|
|
195
206
|
type: 'string',
|
|
196
|
-
description: 'Sub-task title',
|
|
207
|
+
description: 'Sub-task title\n子任务标题',
|
|
197
208
|
},
|
|
198
209
|
estimatedHours: {
|
|
199
210
|
type: 'number',
|
|
200
|
-
description: 'Optional estimated hours',
|
|
211
|
+
description: 'Optional estimated hours\n可选预估工时',
|
|
201
212
|
},
|
|
202
213
|
description: {
|
|
203
214
|
type: 'string',
|
|
204
|
-
description: 'Optional task description',
|
|
215
|
+
description: 'Optional task description\n可选任务描述',
|
|
205
216
|
},
|
|
206
217
|
},
|
|
207
218
|
required: ['projectName', 'taskId', 'parentTaskId', 'title'],
|
|
@@ -209,56 +220,56 @@ const TOOLS = [
|
|
|
209
220
|
},
|
|
210
221
|
{
|
|
211
222
|
name: 'devplan_upsert_task',
|
|
212
|
-
description: 'Idempotent import (upsert) for main tasks or sub-tasks. If the task does not exist, it will be created. If it already exists, it will be updated with the new data while preserving the higher-priority status (e.g., completed tasks will not be reverted to pending). This is the recommended tool for bulk data import to prevent duplicates
|
|
223
|
+
description: 'Idempotent import (upsert) for main tasks or sub-tasks. If the task does not exist, it will be created. If it already exists, it will be updated with the new data while preserving the higher-priority status (e.g., completed tasks will not be reverted to pending). This is the recommended tool for bulk data import to prevent duplicates.\n幂等导入(upsert)主任务或子任务。任务不存在则创建,已存在则更新(保留更高优先级的状态,如已完成的任务不会被回退为待处理)。推荐用于批量数据导入以防重复。',
|
|
213
224
|
inputSchema: {
|
|
214
225
|
type: 'object',
|
|
215
226
|
properties: {
|
|
216
227
|
projectName: {
|
|
217
228
|
type: 'string',
|
|
218
|
-
description: 'Project name',
|
|
229
|
+
description: 'Project name\n项目名称',
|
|
219
230
|
},
|
|
220
231
|
taskType: {
|
|
221
232
|
type: 'string',
|
|
222
233
|
enum: ['main', 'sub'],
|
|
223
|
-
description: 'Whether this is a main task or sub-task',
|
|
234
|
+
description: 'Whether this is a main task or sub-task\n任务类型:主任务 (main) 或子任务 (sub)',
|
|
224
235
|
},
|
|
225
236
|
taskId: {
|
|
226
237
|
type: 'string',
|
|
227
|
-
description: 'Task ID (e.g., "phase-7" for main, "T7.2" for sub)',
|
|
238
|
+
description: 'Task ID (e.g., "phase-7" for main, "T7.2" for sub)\n任务 ID(主任务如 "phase-7",子任务如 "T7.2")',
|
|
228
239
|
},
|
|
229
240
|
title: {
|
|
230
241
|
type: 'string',
|
|
231
|
-
description: 'Task title',
|
|
242
|
+
description: 'Task title\n任务标题',
|
|
232
243
|
},
|
|
233
244
|
priority: {
|
|
234
245
|
type: 'string',
|
|
235
246
|
enum: ['P0', 'P1', 'P2'],
|
|
236
|
-
description: 'Priority level (required for main tasks)',
|
|
247
|
+
description: 'Priority level (required for main tasks)\n优先级(主任务必填)',
|
|
237
248
|
},
|
|
238
249
|
parentTaskId: {
|
|
239
250
|
type: 'string',
|
|
240
|
-
description: 'Parent main task ID (required for sub-tasks)',
|
|
251
|
+
description: 'Parent main task ID (required for sub-tasks)\n所属主任务 ID(子任务必填)',
|
|
241
252
|
},
|
|
242
253
|
description: {
|
|
243
254
|
type: 'string',
|
|
244
|
-
description: 'Optional task description',
|
|
255
|
+
description: 'Optional task description\n可选任务描述',
|
|
245
256
|
},
|
|
246
257
|
estimatedHours: {
|
|
247
258
|
type: 'number',
|
|
248
|
-
description: 'Optional estimated hours',
|
|
259
|
+
description: 'Optional estimated hours\n可选预估工时',
|
|
249
260
|
},
|
|
250
261
|
status: {
|
|
251
262
|
type: 'string',
|
|
252
263
|
enum: ['pending', 'in_progress', 'completed', 'cancelled'],
|
|
253
|
-
description: 'Target status (default: pending). Higher-priority existing status is preserved unless preserveStatus is false
|
|
264
|
+
description: 'Target status (default: pending). Higher-priority existing status is preserved unless preserveStatus is false.\n目标状态(默认 pending)。已有的更高优先级状态会被保留,除非 preserveStatus 为 false。',
|
|
254
265
|
},
|
|
255
266
|
preserveStatus: {
|
|
256
267
|
type: 'boolean',
|
|
257
|
-
description: 'If true (default), existing higher-priority status is preserved. Set to false to force overwrite
|
|
268
|
+
description: 'If true (default), existing higher-priority status is preserved. Set to false to force overwrite.\n为 true(默认)时保留已有的更高优先级状态。设为 false 强制覆盖。',
|
|
258
269
|
},
|
|
259
270
|
moduleId: {
|
|
260
271
|
type: 'string',
|
|
261
|
-
description: 'Optional: Associate with a feature module (main tasks only)',
|
|
272
|
+
description: 'Optional: Associate with a feature module (main tasks only)\n可选:关联到功能模块(仅主任务)',
|
|
262
273
|
},
|
|
263
274
|
},
|
|
264
275
|
required: ['projectName', 'taskType', 'taskId', 'title'],
|
|
@@ -266,22 +277,22 @@ const TOOLS = [
|
|
|
266
277
|
},
|
|
267
278
|
{
|
|
268
279
|
name: 'devplan_complete_task',
|
|
269
|
-
description: 'Mark a task as completed. For sub-tasks: auto-updates parent main task progress count and completedAt timestamp. If all sub-tasks are done, the main task is also auto-completed. For main tasks: directly marks as completed
|
|
280
|
+
description: 'Mark a task as completed. For sub-tasks: auto-updates parent main task progress count and completedAt timestamp. If all sub-tasks are done, the main task is also auto-completed. For main tasks: directly marks as completed.\n将任务标记为已完成。子任务完成时自动更新主任务的进度计数和完成时间戳。当所有子任务完成时,主任务也会自动标记为完成。',
|
|
270
281
|
inputSchema: {
|
|
271
282
|
type: 'object',
|
|
272
283
|
properties: {
|
|
273
284
|
projectName: {
|
|
274
285
|
type: 'string',
|
|
275
|
-
description: 'Project name',
|
|
286
|
+
description: 'Project name\n项目名称',
|
|
276
287
|
},
|
|
277
288
|
taskId: {
|
|
278
289
|
type: 'string',
|
|
279
|
-
description: 'Task ID (sub-task like "T7.2" or main task like "phase-7")',
|
|
290
|
+
description: 'Task ID (sub-task like "T7.2" or main task like "phase-7")\n任务 ID(子任务如 "T7.2",主任务如 "phase-7")',
|
|
280
291
|
},
|
|
281
292
|
taskType: {
|
|
282
293
|
type: 'string',
|
|
283
294
|
enum: ['sub', 'main'],
|
|
284
|
-
description: 'Whether this is a sub-task or main task (default: "sub")',
|
|
295
|
+
description: 'Whether this is a sub-task or main task (default: "sub")\n任务类型:子任务 (sub) 或主任务 (main),默认 "sub"',
|
|
285
296
|
},
|
|
286
297
|
},
|
|
287
298
|
required: ['projectName', 'taskId'],
|
|
@@ -289,31 +300,31 @@ const TOOLS = [
|
|
|
289
300
|
},
|
|
290
301
|
{
|
|
291
302
|
name: 'devplan_list_tasks',
|
|
292
|
-
description: 'List tasks in the dev plan. Can list main tasks, or sub-tasks of a specific main task. When parentTaskId is omitted but status is provided, aggregates sub-tasks across ALL main tasks matching the status filter
|
|
303
|
+
description: 'List tasks in the dev plan. Can list main tasks, or sub-tasks of a specific main task. When parentTaskId is omitted but status is provided, aggregates sub-tasks across ALL main tasks matching the status filter.\n列出开发计划中的任务。可列出主任务,或指定主任务下的子任务。省略 parentTaskId 但提供 status 时,跨所有主任务聚合匹配状态的子任务。',
|
|
293
304
|
inputSchema: {
|
|
294
305
|
type: 'object',
|
|
295
306
|
properties: {
|
|
296
307
|
projectName: {
|
|
297
308
|
type: 'string',
|
|
298
|
-
description: 'Project name',
|
|
309
|
+
description: 'Project name\n项目名称',
|
|
299
310
|
},
|
|
300
311
|
parentTaskId: {
|
|
301
312
|
type: 'string',
|
|
302
|
-
description: 'Optional: List sub-tasks of this main task ID. If omitted, lists main tasks
|
|
313
|
+
description: 'Optional: List sub-tasks of this main task ID. If omitted, lists main tasks.\n可选:指定主任务 ID 以列出其子任务。省略则列出主任务。',
|
|
303
314
|
},
|
|
304
315
|
status: {
|
|
305
316
|
type: 'string',
|
|
306
317
|
enum: ['pending', 'in_progress', 'completed', 'cancelled'],
|
|
307
|
-
description: 'Optional: Filter by status',
|
|
318
|
+
description: 'Optional: Filter by status\n可选:按状态筛选',
|
|
308
319
|
},
|
|
309
320
|
priority: {
|
|
310
321
|
type: 'string',
|
|
311
322
|
enum: ['P0', 'P1', 'P2'],
|
|
312
|
-
description: 'Optional: Filter by priority (main tasks only)',
|
|
323
|
+
description: 'Optional: Filter by priority (main tasks only)\n可选:按优先级筛选(仅主任务)',
|
|
313
324
|
},
|
|
314
325
|
moduleId: {
|
|
315
326
|
type: 'string',
|
|
316
|
-
description: 'Optional: Filter by feature module ID',
|
|
327
|
+
description: 'Optional: Filter by feature module ID\n可选:按功能模块 ID 筛选',
|
|
317
328
|
},
|
|
318
329
|
},
|
|
319
330
|
required: ['projectName'],
|
|
@@ -321,13 +332,13 @@ const TOOLS = [
|
|
|
321
332
|
},
|
|
322
333
|
{
|
|
323
334
|
name: 'devplan_get_progress',
|
|
324
|
-
description: 'Get overall project progress: section count, main task count, sub-task completion rates, per-phase progress bars
|
|
335
|
+
description: 'Get overall project progress: section count, main task count, sub-task completion rates, per-phase progress bars.\n获取项目整体进度概览:文档片段数、主任务数、子任务完成率、各阶段进度条。',
|
|
325
336
|
inputSchema: {
|
|
326
337
|
type: 'object',
|
|
327
338
|
properties: {
|
|
328
339
|
projectName: {
|
|
329
340
|
type: 'string',
|
|
330
|
-
description: 'Project name',
|
|
341
|
+
description: 'Project name\n项目名称',
|
|
331
342
|
},
|
|
332
343
|
},
|
|
333
344
|
required: ['projectName'],
|
|
@@ -335,18 +346,18 @@ const TOOLS = [
|
|
|
335
346
|
},
|
|
336
347
|
{
|
|
337
348
|
name: 'devplan_export_markdown',
|
|
338
|
-
description: 'Export the dev plan as a Markdown document. Scope can be "full" (documents + tasks) or "tasks" (task summary only)
|
|
349
|
+
description: 'Export the dev plan as a Markdown document. Scope can be "full" (documents + tasks) or "tasks" (task summary only).\n将开发计划导出为 Markdown 文档。scope 可选 "full"(文档+任务)或 "tasks"(仅任务摘要)。',
|
|
339
350
|
inputSchema: {
|
|
340
351
|
type: 'object',
|
|
341
352
|
properties: {
|
|
342
353
|
projectName: {
|
|
343
354
|
type: 'string',
|
|
344
|
-
description: 'Project name',
|
|
355
|
+
description: 'Project name\n项目名称',
|
|
345
356
|
},
|
|
346
357
|
scope: {
|
|
347
358
|
type: 'string',
|
|
348
359
|
enum: ['full', 'tasks'],
|
|
349
|
-
description: 'Export scope: "full" for documents + tasks, "tasks" for task summary only (default: "tasks")',
|
|
360
|
+
description: 'Export scope: "full" for documents + tasks, "tasks" for task summary only (default: "tasks")\n导出范围:"full" 包含文档和任务,"tasks" 仅任务摘要(默认 "tasks")',
|
|
350
361
|
},
|
|
351
362
|
},
|
|
352
363
|
required: ['projectName'],
|
|
@@ -354,17 +365,17 @@ const TOOLS = [
|
|
|
354
365
|
},
|
|
355
366
|
{
|
|
356
367
|
name: 'devplan_sync_git',
|
|
357
|
-
description: 'Synchronize DevPlan task statuses with Git history. Checks if completed tasks\' commits are still ancestors of the current HEAD. If a completed task\'s commit was rolled back (e.g., via git reset), the task is automatically reverted to pending. Use dryRun=true to preview changes without modifying data
|
|
368
|
+
description: 'Synchronize DevPlan task statuses with Git history. Checks if completed tasks\' commits are still ancestors of the current HEAD. If a completed task\'s commit was rolled back (e.g., via git reset), the task is automatically reverted to pending. Use dryRun=true to preview changes without modifying data.\n将 DevPlan 任务状态与 Git 历史同步。检查已完成任务的 commit 是否仍是当前 HEAD 的祖先。如果已完成任务的 commit 被回滚(如 git reset),任务会自动回退为待处理。使用 dryRun=true 可预览变更而不修改数据。',
|
|
358
369
|
inputSchema: {
|
|
359
370
|
type: 'object',
|
|
360
371
|
properties: {
|
|
361
372
|
projectName: {
|
|
362
373
|
type: 'string',
|
|
363
|
-
description: 'Project name',
|
|
374
|
+
description: 'Project name\n项目名称',
|
|
364
375
|
},
|
|
365
376
|
dryRun: {
|
|
366
377
|
type: 'boolean',
|
|
367
|
-
description: 'If true, only report which tasks would be reverted without actually changing them (default: false)',
|
|
378
|
+
description: 'If true, only report which tasks would be reverted without actually changing them (default: false)\n为 true 时仅报告哪些任务会被回退,不实际修改数据(默认 false)',
|
|
368
379
|
},
|
|
369
380
|
},
|
|
370
381
|
required: ['projectName'],
|
|
@@ -372,30 +383,30 @@ const TOOLS = [
|
|
|
372
383
|
},
|
|
373
384
|
{
|
|
374
385
|
name: 'devplan_create_module',
|
|
375
|
-
description: 'Create/register a feature module in the dev plan. Modules represent independent functional areas of the project (e.g., "vector-store", "permission-system"). Main tasks and documents can be associated with modules
|
|
386
|
+
description: 'Create/register a feature module in the dev plan. Modules represent independent functional areas of the project (e.g., "vector-store", "permission-system"). Main tasks and documents can be associated with modules.\n在开发计划中创建/注册功能模块。模块代表项目的独立功能区域(如 "vector-store"、"permission-system")。主任务和文档可以关联到模块。',
|
|
376
387
|
inputSchema: {
|
|
377
388
|
type: 'object',
|
|
378
389
|
properties: {
|
|
379
390
|
projectName: {
|
|
380
391
|
type: 'string',
|
|
381
|
-
description: 'Project name',
|
|
392
|
+
description: 'Project name\n项目名称',
|
|
382
393
|
},
|
|
383
394
|
moduleId: {
|
|
384
395
|
type: 'string',
|
|
385
|
-
description: 'Module identifier (e.g., "vector-store", "permission")',
|
|
396
|
+
description: 'Module identifier (e.g., "vector-store", "permission")\n模块标识符(如 "vector-store"、"permission")',
|
|
386
397
|
},
|
|
387
398
|
name: {
|
|
388
399
|
type: 'string',
|
|
389
|
-
description: 'Module display name (e.g., "向量存储模块"
|
|
400
|
+
description: 'Module display name (e.g., "Vector Store Module")\n模块显示名称(如 "向量存储模块")',
|
|
390
401
|
},
|
|
391
402
|
description: {
|
|
392
403
|
type: 'string',
|
|
393
|
-
description: 'Optional module description',
|
|
404
|
+
description: 'Optional module description\n可选模块描述',
|
|
394
405
|
},
|
|
395
406
|
status: {
|
|
396
407
|
type: 'string',
|
|
397
408
|
enum: ['planning', 'active', 'completed', 'deprecated'],
|
|
398
|
-
description: 'Module status (default: active)',
|
|
409
|
+
description: 'Module status (default: active)\n模块状态(默认 active)',
|
|
399
410
|
},
|
|
400
411
|
},
|
|
401
412
|
required: ['projectName', 'moduleId', 'name'],
|
|
@@ -403,18 +414,18 @@ const TOOLS = [
|
|
|
403
414
|
},
|
|
404
415
|
{
|
|
405
416
|
name: 'devplan_list_modules',
|
|
406
|
-
description: 'List all feature modules in the dev plan, with main task count, sub-task count (total and completed), and document counts
|
|
417
|
+
description: 'List all feature modules in the dev plan, with main task count, sub-task count (total and completed), and document counts.\n列出开发计划中的所有功能模块,包含主任务数、子任务数(总数和已完成数)、文档数。',
|
|
407
418
|
inputSchema: {
|
|
408
419
|
type: 'object',
|
|
409
420
|
properties: {
|
|
410
421
|
projectName: {
|
|
411
422
|
type: 'string',
|
|
412
|
-
description: 'Project name',
|
|
423
|
+
description: 'Project name\n项目名称',
|
|
413
424
|
},
|
|
414
425
|
status: {
|
|
415
426
|
type: 'string',
|
|
416
427
|
enum: ['planning', 'active', 'completed', 'deprecated'],
|
|
417
|
-
description: 'Optional: Filter by module status',
|
|
428
|
+
description: 'Optional: Filter by module status\n可选:按模块状态筛选',
|
|
418
429
|
},
|
|
419
430
|
},
|
|
420
431
|
required: ['projectName'],
|
|
@@ -422,17 +433,17 @@ const TOOLS = [
|
|
|
422
433
|
},
|
|
423
434
|
{
|
|
424
435
|
name: 'devplan_get_module',
|
|
425
|
-
description: 'Get module details including all associated main tasks, sub-tasks, and documents
|
|
436
|
+
description: 'Get module details including all associated main tasks, sub-tasks, and documents.\n获取模块详情,包含所有关联的主任务、子任务和文档。',
|
|
426
437
|
inputSchema: {
|
|
427
438
|
type: 'object',
|
|
428
439
|
properties: {
|
|
429
440
|
projectName: {
|
|
430
441
|
type: 'string',
|
|
431
|
-
description: 'Project name',
|
|
442
|
+
description: 'Project name\n项目名称',
|
|
432
443
|
},
|
|
433
444
|
moduleId: {
|
|
434
445
|
type: 'string',
|
|
435
|
-
description: 'Module identifier',
|
|
446
|
+
description: 'Module identifier\n模块标识符',
|
|
436
447
|
},
|
|
437
448
|
},
|
|
438
449
|
required: ['projectName', 'moduleId'],
|
|
@@ -440,58 +451,133 @@ const TOOLS = [
|
|
|
440
451
|
},
|
|
441
452
|
{
|
|
442
453
|
name: 'devplan_update_module',
|
|
443
|
-
description: 'Update module information (name, description, status)
|
|
454
|
+
description: 'Update module information (name, description, status).\n更新模块信息(名称、描述、状态)。',
|
|
444
455
|
inputSchema: {
|
|
445
456
|
type: 'object',
|
|
446
457
|
properties: {
|
|
447
458
|
projectName: {
|
|
448
459
|
type: 'string',
|
|
449
|
-
description: 'Project name',
|
|
460
|
+
description: 'Project name\n项目名称',
|
|
450
461
|
},
|
|
451
462
|
moduleId: {
|
|
452
463
|
type: 'string',
|
|
453
|
-
description: 'Module identifier',
|
|
464
|
+
description: 'Module identifier\n模块标识符',
|
|
454
465
|
},
|
|
455
466
|
name: {
|
|
456
467
|
type: 'string',
|
|
457
|
-
description: 'New module name',
|
|
468
|
+
description: 'New module name\n新的模块名称',
|
|
458
469
|
},
|
|
459
470
|
description: {
|
|
460
471
|
type: 'string',
|
|
461
|
-
description: 'New module description',
|
|
472
|
+
description: 'New module description\n新的模块描述',
|
|
462
473
|
},
|
|
463
474
|
status: {
|
|
464
475
|
type: 'string',
|
|
465
476
|
enum: ['planning', 'active', 'completed', 'deprecated'],
|
|
466
|
-
description: 'New module status',
|
|
477
|
+
description: 'New module status\n新的模块状态',
|
|
467
478
|
},
|
|
468
479
|
},
|
|
469
480
|
required: ['projectName', 'moduleId'],
|
|
470
481
|
},
|
|
471
482
|
},
|
|
483
|
+
{
|
|
484
|
+
name: 'devplan_export_graph',
|
|
485
|
+
description: 'Export the DevPlan as a graph structure (nodes + edges) for visualization. Only available when the project uses the "graph" engine (SocialGraphV2). Returns { nodes, edges } compatible with vis-network.\n将 DevPlan 导出为图结构(节点+边)用于可视化。仅在项目使用 "graph" 引擎 (SocialGraphV2) 时可用。返回兼容 vis-network 的 { nodes, edges }。',
|
|
486
|
+
inputSchema: {
|
|
487
|
+
type: 'object',
|
|
488
|
+
properties: {
|
|
489
|
+
projectName: {
|
|
490
|
+
type: 'string',
|
|
491
|
+
description: 'Project name\n项目名称',
|
|
492
|
+
},
|
|
493
|
+
includeDocuments: {
|
|
494
|
+
type: 'boolean',
|
|
495
|
+
description: 'Whether to include document nodes (default: true)\n是否包含文档节点(默认 true)',
|
|
496
|
+
},
|
|
497
|
+
includeModules: {
|
|
498
|
+
type: 'boolean',
|
|
499
|
+
description: 'Whether to include module nodes (default: true)\n是否包含模块节点(默认 true)',
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
required: ['projectName'],
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
name: 'devplan_migrate_engine',
|
|
507
|
+
description: 'Migrate project data between storage engines. Supports migration from "document" (EnhancedDocumentStore/JSONL) to "graph" (SocialGraphV2) or vice versa. Automatically backs up old data before migration. Use dryRun=true to preview without changes.\n在存储引擎之间迁移项目数据。支持从 "document"(EnhancedDocumentStore/JSONL)迁移到 "graph"(SocialGraphV2),或反向迁移。迁移前自动备份旧数据。使用 dryRun=true 可预览而不实际修改。',
|
|
508
|
+
inputSchema: {
|
|
509
|
+
type: 'object',
|
|
510
|
+
properties: {
|
|
511
|
+
projectName: {
|
|
512
|
+
type: 'string',
|
|
513
|
+
description: 'Project name\n项目名称',
|
|
514
|
+
},
|
|
515
|
+
targetEngine: {
|
|
516
|
+
type: 'string',
|
|
517
|
+
enum: ['graph', 'document'],
|
|
518
|
+
description: 'Target engine to migrate to\n目标引擎类型',
|
|
519
|
+
},
|
|
520
|
+
backup: {
|
|
521
|
+
type: 'boolean',
|
|
522
|
+
description: 'Whether to backup old data before migration (default: true)\n是否在迁移前备份旧数据(默认 true)',
|
|
523
|
+
},
|
|
524
|
+
dryRun: {
|
|
525
|
+
type: 'boolean',
|
|
526
|
+
description: 'If true, only preview what would be migrated without making changes (default: false)\n为 true 时仅预览迁移内容,不实际修改(默认 false)',
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
required: ['projectName', 'targetEngine'],
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
name: 'devplan_start_visual',
|
|
534
|
+
description: 'Start the graph visualization HTTP server. Opens an interactive vis-network page in the browser to visualize modules, tasks, and their relationships as a graph. The server runs in the background. Only works with projects using the "graph" engine.\n启动图谱可视化 HTTP 服务器。在浏览器中打开交互式 vis-network 页面,将模块、任务及其关系以图谱形式可视化展示。服务器在后台运行。仅支持使用 "graph" 引擎的项目。',
|
|
535
|
+
inputSchema: {
|
|
536
|
+
type: 'object',
|
|
537
|
+
properties: {
|
|
538
|
+
projectName: {
|
|
539
|
+
type: 'string',
|
|
540
|
+
description: 'Project name\n项目名称',
|
|
541
|
+
},
|
|
542
|
+
port: {
|
|
543
|
+
type: 'number',
|
|
544
|
+
description: 'HTTP server port (default: 3210)\nHTTP 服务器端口(默认 3210)',
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
required: ['projectName'],
|
|
548
|
+
},
|
|
549
|
+
},
|
|
472
550
|
];
|
|
473
551
|
async function handleToolCall(name, args) {
|
|
474
552
|
switch (name) {
|
|
475
553
|
case 'devplan_init': {
|
|
476
554
|
if (!args.projectName) {
|
|
477
|
-
// List existing plans
|
|
478
|
-
const plans = (0,
|
|
555
|
+
// List existing plans with engine info
|
|
556
|
+
const plans = (0, dev_plan_factory_1.listDevPlans)();
|
|
557
|
+
const planDetails = plans.map((name) => ({
|
|
558
|
+
name,
|
|
559
|
+
engine: (0, dev_plan_factory_1.getProjectEngine)(name) || 'unknown',
|
|
560
|
+
}));
|
|
479
561
|
return JSON.stringify({
|
|
480
|
-
existingPlans:
|
|
481
|
-
availableSections:
|
|
482
|
-
sectionDescriptions:
|
|
562
|
+
existingPlans: planDetails,
|
|
563
|
+
availableSections: types_1.ALL_SECTIONS,
|
|
564
|
+
sectionDescriptions: types_1.SECTION_DESCRIPTIONS,
|
|
565
|
+
availableEngines: ['graph', 'document'],
|
|
566
|
+
defaultEngine: 'graph',
|
|
483
567
|
message: plans.length > 0
|
|
484
568
|
? `Found ${plans.length} existing plan(s). Provide a projectName to initialize a new one.`
|
|
485
569
|
: 'No existing plans. Provide a projectName to create one.',
|
|
486
570
|
});
|
|
487
571
|
}
|
|
488
572
|
const plan = getDevPlan(args.projectName);
|
|
573
|
+
const engine = (0, dev_plan_factory_1.getProjectEngine)(args.projectName) || 'graph';
|
|
489
574
|
return JSON.stringify({
|
|
490
575
|
success: true,
|
|
491
576
|
projectName: args.projectName,
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
577
|
+
engine,
|
|
578
|
+
availableSections: types_1.ALL_SECTIONS,
|
|
579
|
+
sectionDescriptions: types_1.SECTION_DESCRIPTIONS,
|
|
580
|
+
message: `DevPlan initialized for "${args.projectName}" with engine "${engine}". Use devplan_save_section to add document sections and devplan_create_main_task to add development phases.`,
|
|
495
581
|
});
|
|
496
582
|
}
|
|
497
583
|
case 'devplan_save_section': {
|
|
@@ -950,6 +1036,132 @@ async function handleToolCall(name, args) {
|
|
|
950
1036
|
}
|
|
951
1037
|
return JSON.stringify({ success: true, module: updated });
|
|
952
1038
|
}
|
|
1039
|
+
case 'devplan_export_graph': {
|
|
1040
|
+
if (!args.projectName) {
|
|
1041
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
1042
|
+
}
|
|
1043
|
+
const plan = getDevPlan(args.projectName);
|
|
1044
|
+
const engine = (0, dev_plan_factory_1.getProjectEngine)(args.projectName);
|
|
1045
|
+
if (engine !== 'graph' || !plan.exportGraph) {
|
|
1046
|
+
return JSON.stringify({
|
|
1047
|
+
error: `Graph export is only available for projects using the "graph" engine. Project "${args.projectName}" uses "${engine || 'document'}" engine.`,
|
|
1048
|
+
hint: 'Re-initialize the project with engine "graph" to enable graph export.',
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
try {
|
|
1052
|
+
const graph = plan.exportGraph({
|
|
1053
|
+
includeDocuments: args.includeDocuments,
|
|
1054
|
+
includeModules: args.includeModules,
|
|
1055
|
+
});
|
|
1056
|
+
return JSON.stringify({
|
|
1057
|
+
success: true,
|
|
1058
|
+
projectName: args.projectName,
|
|
1059
|
+
engine: 'graph',
|
|
1060
|
+
nodeCount: graph?.nodes.length || 0,
|
|
1061
|
+
edgeCount: graph?.edges.length || 0,
|
|
1062
|
+
graph,
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
catch (err) {
|
|
1066
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, err instanceof Error ? err.message : String(err));
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
case 'devplan_migrate_engine': {
|
|
1070
|
+
if (!args.projectName || !args.targetEngine) {
|
|
1071
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, targetEngine');
|
|
1072
|
+
}
|
|
1073
|
+
const validEngines = ['graph', 'document'];
|
|
1074
|
+
if (!validEngines.includes(args.targetEngine)) {
|
|
1075
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, `Invalid targetEngine "${args.targetEngine}". Must be one of: ${validEngines.join(', ')}`);
|
|
1076
|
+
}
|
|
1077
|
+
try {
|
|
1078
|
+
const result = (0, dev_plan_migrate_1.migrateEngine)(args.projectName, args.targetEngine, undefined, {
|
|
1079
|
+
backup: args.backup,
|
|
1080
|
+
dryRun: args.dryRun,
|
|
1081
|
+
});
|
|
1082
|
+
// 迁移成功后清除缓存,下次访问时使用新引擎
|
|
1083
|
+
if (result.success && !args.dryRun) {
|
|
1084
|
+
devPlanCache.delete(args.projectName);
|
|
1085
|
+
}
|
|
1086
|
+
const statusIcon = result.success ? '✅' : '⚠️';
|
|
1087
|
+
const modeLabel = args.dryRun ? ' (dry run)' : '';
|
|
1088
|
+
return JSON.stringify({
|
|
1089
|
+
...result,
|
|
1090
|
+
summary: result.fromEngine === result.toEngine
|
|
1091
|
+
? `ℹ️ Project "${args.projectName}" already uses "${result.toEngine}" engine. No migration needed.`
|
|
1092
|
+
: result.success
|
|
1093
|
+
? `${statusIcon} Successfully migrated "${args.projectName}" from "${result.fromEngine}" to "${result.toEngine}"${modeLabel}. ` +
|
|
1094
|
+
`Stats: ${result.stats.modules} modules, ${result.stats.documents} documents, ` +
|
|
1095
|
+
`${result.stats.mainTasks} main tasks, ${result.stats.subTasks} sub-tasks. ` +
|
|
1096
|
+
`Duration: ${result.durationMs}ms.` +
|
|
1097
|
+
(result.backupPath ? ` Backup: ${result.backupPath}` : '')
|
|
1098
|
+
: `${statusIcon} Migration failed with ${result.errors.length} error(s): ${result.errors.join('; ')}`,
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
catch (err) {
|
|
1102
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, err instanceof Error ? err.message : String(err));
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
case 'devplan_start_visual': {
|
|
1106
|
+
if (!args.projectName) {
|
|
1107
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
1108
|
+
}
|
|
1109
|
+
const engine = (0, dev_plan_factory_1.getProjectEngine)(args.projectName);
|
|
1110
|
+
if (engine !== 'graph') {
|
|
1111
|
+
return JSON.stringify({
|
|
1112
|
+
success: false,
|
|
1113
|
+
error: `Graph visualization requires "graph" engine. Project "${args.projectName}" uses "${engine || 'document'}" engine.`,
|
|
1114
|
+
hint: 'Use devplan_migrate_engine to migrate to "graph" engine first.',
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
const port = args.port || 3210;
|
|
1118
|
+
try {
|
|
1119
|
+
const { spawn } = require('child_process');
|
|
1120
|
+
const serverScript = require('path').resolve(__dirname, '../visualize/server.js');
|
|
1121
|
+
const child = spawn(process.execPath, [
|
|
1122
|
+
serverScript,
|
|
1123
|
+
'--project', args.projectName,
|
|
1124
|
+
'--port', String(port),
|
|
1125
|
+
], {
|
|
1126
|
+
detached: true,
|
|
1127
|
+
stdio: 'ignore',
|
|
1128
|
+
});
|
|
1129
|
+
child.unref();
|
|
1130
|
+
const url = `http://localhost:${port}`;
|
|
1131
|
+
// 尝试自动打开浏览器
|
|
1132
|
+
const platform = process.platform;
|
|
1133
|
+
let openCmd;
|
|
1134
|
+
let openArgs;
|
|
1135
|
+
if (platform === 'win32') {
|
|
1136
|
+
openCmd = 'cmd';
|
|
1137
|
+
openArgs = ['/c', 'start', '', url];
|
|
1138
|
+
}
|
|
1139
|
+
else if (platform === 'darwin') {
|
|
1140
|
+
openCmd = 'open';
|
|
1141
|
+
openArgs = [url];
|
|
1142
|
+
}
|
|
1143
|
+
else {
|
|
1144
|
+
openCmd = 'xdg-open';
|
|
1145
|
+
openArgs = [url];
|
|
1146
|
+
}
|
|
1147
|
+
const browser = spawn(openCmd, openArgs, {
|
|
1148
|
+
detached: true,
|
|
1149
|
+
stdio: 'ignore',
|
|
1150
|
+
});
|
|
1151
|
+
browser.unref();
|
|
1152
|
+
return JSON.stringify({
|
|
1153
|
+
success: true,
|
|
1154
|
+
projectName: args.projectName,
|
|
1155
|
+
port,
|
|
1156
|
+
url,
|
|
1157
|
+
pid: child.pid,
|
|
1158
|
+
message: `Visualization server started at ${url} (PID: ${child.pid}). Browser should open automatically. Use Ctrl+Click to drag connected nodes together.`,
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
catch (err) {
|
|
1162
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, err instanceof Error ? err.message : String(err));
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
953
1165
|
default:
|
|
954
1166
|
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
955
1167
|
}
|