aifastdb-devplan 1.0.0
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/LICENSE +21 -0
- package/README.md +112 -0
- package/dist/dev-plan-store.d.ts +656 -0
- package/dist/dev-plan-store.d.ts.map +1 -0
- package/dist/dev-plan-store.js +1685 -0
- package/dist/dev-plan-store.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/index.d.ts +26 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +1004 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,1004 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* aifastdb-devplan MCP Server
|
|
5
|
+
*
|
|
6
|
+
* 通用开发计划管理 MCP Server,使用 aifastdb 作为存储引擎。
|
|
7
|
+
*
|
|
8
|
+
* Tools (DevPlan — 通用开发计划管理):
|
|
9
|
+
* - devplan_init: Initialize a dev plan for a project
|
|
10
|
+
* - devplan_save_section: Save/update a document section
|
|
11
|
+
* - devplan_get_section: Read a document section
|
|
12
|
+
* - devplan_list_sections: List all document sections
|
|
13
|
+
* - devplan_create_main_task: Create a main task (development phase)
|
|
14
|
+
* - devplan_add_sub_task: Add a sub task under a main task
|
|
15
|
+
* - devplan_upsert_task: Idempotent import (upsert) main/sub tasks — prevents duplicates
|
|
16
|
+
* - devplan_complete_task: Complete a task (auto-updates progress, anchors Git commit)
|
|
17
|
+
* - devplan_list_tasks: List tasks with optional filters
|
|
18
|
+
* - devplan_get_progress: Get project progress overview
|
|
19
|
+
* - devplan_export_markdown: Export plan as Markdown
|
|
20
|
+
* - devplan_sync_git: Sync task statuses with Git history (revert rolled-back tasks)
|
|
21
|
+
* - devplan_create_module: Create/register a feature module
|
|
22
|
+
* - devplan_list_modules: List all feature modules
|
|
23
|
+
* - devplan_get_module: Get module details with associated tasks and docs
|
|
24
|
+
* - devplan_update_module: Update module info
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
// @ts-ignore - MCP SDK types will be available after npm install
|
|
28
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
29
|
+
// @ts-ignore - MCP SDK types will be available after npm install
|
|
30
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
31
|
+
// @ts-ignore - MCP SDK types will be available after npm install
|
|
32
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
33
|
+
const dev_plan_store_1 = require("../dev-plan-store");
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// DevPlan Store Cache
|
|
36
|
+
// ============================================================================
|
|
37
|
+
const devPlanCache = new Map();
|
|
38
|
+
function getDevPlan(projectName) {
|
|
39
|
+
if (!devPlanCache.has(projectName)) {
|
|
40
|
+
devPlanCache.set(projectName, (0, dev_plan_store_1.createDevPlan)(projectName));
|
|
41
|
+
}
|
|
42
|
+
return devPlanCache.get(projectName);
|
|
43
|
+
}
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Tool Definitions
|
|
46
|
+
// ============================================================================
|
|
47
|
+
const TOOLS = [
|
|
48
|
+
{
|
|
49
|
+
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.',
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
projectName: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Project name (e.g., "federation-db", "aidb-viewer"). Omit to list existing plans.',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
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.',
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
properties: {
|
|
67
|
+
projectName: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
description: 'Project name',
|
|
70
|
+
},
|
|
71
|
+
section: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
enum: ['overview', 'core_concepts', 'api_design', 'file_structure', 'config', 'examples', 'technical_notes', 'api_endpoints', 'milestones', 'changelog', 'custom'],
|
|
74
|
+
description: 'Document section type',
|
|
75
|
+
},
|
|
76
|
+
title: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
description: 'Section title (e.g., "概述 - 背景与目标")',
|
|
79
|
+
},
|
|
80
|
+
content: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
description: 'Markdown content for this section',
|
|
83
|
+
},
|
|
84
|
+
version: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
description: 'Optional version string (default: "1.0.0")',
|
|
87
|
+
},
|
|
88
|
+
subSection: {
|
|
89
|
+
type: 'string',
|
|
90
|
+
description: 'Optional sub-section name for technical_notes/custom (e.g., "security", "resilience")',
|
|
91
|
+
},
|
|
92
|
+
moduleId: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
description: 'Optional: Associate with a feature module',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
required: ['projectName', 'section', 'title', 'content'],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'devplan_get_section',
|
|
102
|
+
description: 'Read a specific document section from the dev plan.',
|
|
103
|
+
inputSchema: {
|
|
104
|
+
type: 'object',
|
|
105
|
+
properties: {
|
|
106
|
+
projectName: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
description: 'Project name',
|
|
109
|
+
},
|
|
110
|
+
section: {
|
|
111
|
+
type: 'string',
|
|
112
|
+
enum: ['overview', 'core_concepts', 'api_design', 'file_structure', 'config', 'examples', 'technical_notes', 'api_endpoints', 'milestones', 'changelog', 'custom'],
|
|
113
|
+
description: 'Document section type',
|
|
114
|
+
},
|
|
115
|
+
subSection: {
|
|
116
|
+
type: 'string',
|
|
117
|
+
description: 'Optional sub-section name',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
required: ['projectName', 'section'],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'devplan_list_sections',
|
|
125
|
+
description: 'List all document sections in the dev plan for a project.',
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: 'object',
|
|
128
|
+
properties: {
|
|
129
|
+
projectName: {
|
|
130
|
+
type: 'string',
|
|
131
|
+
description: 'Project name',
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
required: ['projectName'],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'devplan_create_main_task',
|
|
139
|
+
description: 'Create a main task (development phase) in the dev plan. A main task groups multiple sub-tasks.',
|
|
140
|
+
inputSchema: {
|
|
141
|
+
type: 'object',
|
|
142
|
+
properties: {
|
|
143
|
+
projectName: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'Project name',
|
|
146
|
+
},
|
|
147
|
+
taskId: {
|
|
148
|
+
type: 'string',
|
|
149
|
+
description: 'Main task ID (e.g., "phase-7", "phase-14B")',
|
|
150
|
+
},
|
|
151
|
+
title: {
|
|
152
|
+
type: 'string',
|
|
153
|
+
description: 'Task title (e.g., "阶段七:Store Trait 与适配器")',
|
|
154
|
+
},
|
|
155
|
+
priority: {
|
|
156
|
+
type: 'string',
|
|
157
|
+
enum: ['P0', 'P1', 'P2'],
|
|
158
|
+
description: 'Priority level',
|
|
159
|
+
},
|
|
160
|
+
description: {
|
|
161
|
+
type: 'string',
|
|
162
|
+
description: 'Optional task description',
|
|
163
|
+
},
|
|
164
|
+
estimatedHours: {
|
|
165
|
+
type: 'number',
|
|
166
|
+
description: 'Optional estimated hours',
|
|
167
|
+
},
|
|
168
|
+
moduleId: {
|
|
169
|
+
type: 'string',
|
|
170
|
+
description: 'Optional: Associate with a feature module',
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
required: ['projectName', 'taskId', 'title', 'priority'],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'devplan_add_sub_task',
|
|
178
|
+
description: 'Add a sub-task under a main task. Sub-tasks correspond to Cursor TodoList items.',
|
|
179
|
+
inputSchema: {
|
|
180
|
+
type: 'object',
|
|
181
|
+
properties: {
|
|
182
|
+
projectName: {
|
|
183
|
+
type: 'string',
|
|
184
|
+
description: 'Project name',
|
|
185
|
+
},
|
|
186
|
+
taskId: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
description: 'Sub-task ID (e.g., "T7.2", "T14.8")',
|
|
189
|
+
},
|
|
190
|
+
parentTaskId: {
|
|
191
|
+
type: 'string',
|
|
192
|
+
description: 'Parent main task ID (e.g., "phase-7")',
|
|
193
|
+
},
|
|
194
|
+
title: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
description: 'Sub-task title',
|
|
197
|
+
},
|
|
198
|
+
estimatedHours: {
|
|
199
|
+
type: 'number',
|
|
200
|
+
description: 'Optional estimated hours',
|
|
201
|
+
},
|
|
202
|
+
description: {
|
|
203
|
+
type: 'string',
|
|
204
|
+
description: 'Optional task description',
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
required: ['projectName', 'taskId', 'parentTaskId', 'title'],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
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.',
|
|
213
|
+
inputSchema: {
|
|
214
|
+
type: 'object',
|
|
215
|
+
properties: {
|
|
216
|
+
projectName: {
|
|
217
|
+
type: 'string',
|
|
218
|
+
description: 'Project name',
|
|
219
|
+
},
|
|
220
|
+
taskType: {
|
|
221
|
+
type: 'string',
|
|
222
|
+
enum: ['main', 'sub'],
|
|
223
|
+
description: 'Whether this is a main task or sub-task',
|
|
224
|
+
},
|
|
225
|
+
taskId: {
|
|
226
|
+
type: 'string',
|
|
227
|
+
description: 'Task ID (e.g., "phase-7" for main, "T7.2" for sub)',
|
|
228
|
+
},
|
|
229
|
+
title: {
|
|
230
|
+
type: 'string',
|
|
231
|
+
description: 'Task title',
|
|
232
|
+
},
|
|
233
|
+
priority: {
|
|
234
|
+
type: 'string',
|
|
235
|
+
enum: ['P0', 'P1', 'P2'],
|
|
236
|
+
description: 'Priority level (required for main tasks)',
|
|
237
|
+
},
|
|
238
|
+
parentTaskId: {
|
|
239
|
+
type: 'string',
|
|
240
|
+
description: 'Parent main task ID (required for sub-tasks)',
|
|
241
|
+
},
|
|
242
|
+
description: {
|
|
243
|
+
type: 'string',
|
|
244
|
+
description: 'Optional task description',
|
|
245
|
+
},
|
|
246
|
+
estimatedHours: {
|
|
247
|
+
type: 'number',
|
|
248
|
+
description: 'Optional estimated hours',
|
|
249
|
+
},
|
|
250
|
+
status: {
|
|
251
|
+
type: 'string',
|
|
252
|
+
enum: ['pending', 'in_progress', 'completed', 'cancelled'],
|
|
253
|
+
description: 'Target status (default: pending). Higher-priority existing status is preserved unless preserveStatus is false.',
|
|
254
|
+
},
|
|
255
|
+
preserveStatus: {
|
|
256
|
+
type: 'boolean',
|
|
257
|
+
description: 'If true (default), existing higher-priority status is preserved. Set to false to force overwrite.',
|
|
258
|
+
},
|
|
259
|
+
moduleId: {
|
|
260
|
+
type: 'string',
|
|
261
|
+
description: 'Optional: Associate with a feature module (main tasks only)',
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
required: ['projectName', 'taskType', 'taskId', 'title'],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
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.',
|
|
270
|
+
inputSchema: {
|
|
271
|
+
type: 'object',
|
|
272
|
+
properties: {
|
|
273
|
+
projectName: {
|
|
274
|
+
type: 'string',
|
|
275
|
+
description: 'Project name',
|
|
276
|
+
},
|
|
277
|
+
taskId: {
|
|
278
|
+
type: 'string',
|
|
279
|
+
description: 'Task ID (sub-task like "T7.2" or main task like "phase-7")',
|
|
280
|
+
},
|
|
281
|
+
taskType: {
|
|
282
|
+
type: 'string',
|
|
283
|
+
enum: ['sub', 'main'],
|
|
284
|
+
description: 'Whether this is a sub-task or main task (default: "sub")',
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
required: ['projectName', 'taskId'],
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
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.',
|
|
293
|
+
inputSchema: {
|
|
294
|
+
type: 'object',
|
|
295
|
+
properties: {
|
|
296
|
+
projectName: {
|
|
297
|
+
type: 'string',
|
|
298
|
+
description: 'Project name',
|
|
299
|
+
},
|
|
300
|
+
parentTaskId: {
|
|
301
|
+
type: 'string',
|
|
302
|
+
description: 'Optional: List sub-tasks of this main task ID. If omitted, lists main tasks.',
|
|
303
|
+
},
|
|
304
|
+
status: {
|
|
305
|
+
type: 'string',
|
|
306
|
+
enum: ['pending', 'in_progress', 'completed', 'cancelled'],
|
|
307
|
+
description: 'Optional: Filter by status',
|
|
308
|
+
},
|
|
309
|
+
priority: {
|
|
310
|
+
type: 'string',
|
|
311
|
+
enum: ['P0', 'P1', 'P2'],
|
|
312
|
+
description: 'Optional: Filter by priority (main tasks only)',
|
|
313
|
+
},
|
|
314
|
+
moduleId: {
|
|
315
|
+
type: 'string',
|
|
316
|
+
description: 'Optional: Filter by feature module ID',
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
required: ['projectName'],
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: 'devplan_get_progress',
|
|
324
|
+
description: 'Get overall project progress: section count, main task count, sub-task completion rates, per-phase progress bars.',
|
|
325
|
+
inputSchema: {
|
|
326
|
+
type: 'object',
|
|
327
|
+
properties: {
|
|
328
|
+
projectName: {
|
|
329
|
+
type: 'string',
|
|
330
|
+
description: 'Project name',
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
required: ['projectName'],
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
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).',
|
|
339
|
+
inputSchema: {
|
|
340
|
+
type: 'object',
|
|
341
|
+
properties: {
|
|
342
|
+
projectName: {
|
|
343
|
+
type: 'string',
|
|
344
|
+
description: 'Project name',
|
|
345
|
+
},
|
|
346
|
+
scope: {
|
|
347
|
+
type: 'string',
|
|
348
|
+
enum: ['full', 'tasks'],
|
|
349
|
+
description: 'Export scope: "full" for documents + tasks, "tasks" for task summary only (default: "tasks")',
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
required: ['projectName'],
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
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.',
|
|
358
|
+
inputSchema: {
|
|
359
|
+
type: 'object',
|
|
360
|
+
properties: {
|
|
361
|
+
projectName: {
|
|
362
|
+
type: 'string',
|
|
363
|
+
description: 'Project name',
|
|
364
|
+
},
|
|
365
|
+
dryRun: {
|
|
366
|
+
type: 'boolean',
|
|
367
|
+
description: 'If true, only report which tasks would be reverted without actually changing them (default: false)',
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
required: ['projectName'],
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
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.',
|
|
376
|
+
inputSchema: {
|
|
377
|
+
type: 'object',
|
|
378
|
+
properties: {
|
|
379
|
+
projectName: {
|
|
380
|
+
type: 'string',
|
|
381
|
+
description: 'Project name',
|
|
382
|
+
},
|
|
383
|
+
moduleId: {
|
|
384
|
+
type: 'string',
|
|
385
|
+
description: 'Module identifier (e.g., "vector-store", "permission")',
|
|
386
|
+
},
|
|
387
|
+
name: {
|
|
388
|
+
type: 'string',
|
|
389
|
+
description: 'Module display name (e.g., "向量存储模块")',
|
|
390
|
+
},
|
|
391
|
+
description: {
|
|
392
|
+
type: 'string',
|
|
393
|
+
description: 'Optional module description',
|
|
394
|
+
},
|
|
395
|
+
status: {
|
|
396
|
+
type: 'string',
|
|
397
|
+
enum: ['planning', 'active', 'completed', 'deprecated'],
|
|
398
|
+
description: 'Module status (default: active)',
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
required: ['projectName', 'moduleId', 'name'],
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
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.',
|
|
407
|
+
inputSchema: {
|
|
408
|
+
type: 'object',
|
|
409
|
+
properties: {
|
|
410
|
+
projectName: {
|
|
411
|
+
type: 'string',
|
|
412
|
+
description: 'Project name',
|
|
413
|
+
},
|
|
414
|
+
status: {
|
|
415
|
+
type: 'string',
|
|
416
|
+
enum: ['planning', 'active', 'completed', 'deprecated'],
|
|
417
|
+
description: 'Optional: Filter by module status',
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
required: ['projectName'],
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: 'devplan_get_module',
|
|
425
|
+
description: 'Get module details including all associated main tasks, sub-tasks, and documents.',
|
|
426
|
+
inputSchema: {
|
|
427
|
+
type: 'object',
|
|
428
|
+
properties: {
|
|
429
|
+
projectName: {
|
|
430
|
+
type: 'string',
|
|
431
|
+
description: 'Project name',
|
|
432
|
+
},
|
|
433
|
+
moduleId: {
|
|
434
|
+
type: 'string',
|
|
435
|
+
description: 'Module identifier',
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
required: ['projectName', 'moduleId'],
|
|
439
|
+
},
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
name: 'devplan_update_module',
|
|
443
|
+
description: 'Update module information (name, description, status).',
|
|
444
|
+
inputSchema: {
|
|
445
|
+
type: 'object',
|
|
446
|
+
properties: {
|
|
447
|
+
projectName: {
|
|
448
|
+
type: 'string',
|
|
449
|
+
description: 'Project name',
|
|
450
|
+
},
|
|
451
|
+
moduleId: {
|
|
452
|
+
type: 'string',
|
|
453
|
+
description: 'Module identifier',
|
|
454
|
+
},
|
|
455
|
+
name: {
|
|
456
|
+
type: 'string',
|
|
457
|
+
description: 'New module name',
|
|
458
|
+
},
|
|
459
|
+
description: {
|
|
460
|
+
type: 'string',
|
|
461
|
+
description: 'New module description',
|
|
462
|
+
},
|
|
463
|
+
status: {
|
|
464
|
+
type: 'string',
|
|
465
|
+
enum: ['planning', 'active', 'completed', 'deprecated'],
|
|
466
|
+
description: 'New module status',
|
|
467
|
+
},
|
|
468
|
+
},
|
|
469
|
+
required: ['projectName', 'moduleId'],
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
];
|
|
473
|
+
async function handleToolCall(name, args) {
|
|
474
|
+
switch (name) {
|
|
475
|
+
case 'devplan_init': {
|
|
476
|
+
if (!args.projectName) {
|
|
477
|
+
// List existing plans
|
|
478
|
+
const plans = (0, dev_plan_store_1.listDevPlans)();
|
|
479
|
+
return JSON.stringify({
|
|
480
|
+
existingPlans: plans,
|
|
481
|
+
availableSections: dev_plan_store_1.ALL_SECTIONS,
|
|
482
|
+
sectionDescriptions: dev_plan_store_1.SECTION_DESCRIPTIONS,
|
|
483
|
+
message: plans.length > 0
|
|
484
|
+
? `Found ${plans.length} existing plan(s). Provide a projectName to initialize a new one.`
|
|
485
|
+
: 'No existing plans. Provide a projectName to create one.',
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
const plan = getDevPlan(args.projectName);
|
|
489
|
+
return JSON.stringify({
|
|
490
|
+
success: true,
|
|
491
|
+
projectName: args.projectName,
|
|
492
|
+
availableSections: dev_plan_store_1.ALL_SECTIONS,
|
|
493
|
+
sectionDescriptions: dev_plan_store_1.SECTION_DESCRIPTIONS,
|
|
494
|
+
message: `DevPlan initialized for "${args.projectName}". Use devplan_save_section to add document sections and devplan_create_main_task to add development phases.`,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
case 'devplan_save_section': {
|
|
498
|
+
if (!args.projectName || !args.section || !args.title || !args.content) {
|
|
499
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, section, title, content');
|
|
500
|
+
}
|
|
501
|
+
const plan = getDevPlan(args.projectName);
|
|
502
|
+
const id = plan.saveSection({
|
|
503
|
+
projectName: args.projectName,
|
|
504
|
+
section: args.section,
|
|
505
|
+
title: args.title,
|
|
506
|
+
content: args.content,
|
|
507
|
+
version: args.version,
|
|
508
|
+
subSection: args.subSection,
|
|
509
|
+
moduleId: args.moduleId,
|
|
510
|
+
});
|
|
511
|
+
return JSON.stringify({
|
|
512
|
+
success: true,
|
|
513
|
+
documentId: id,
|
|
514
|
+
projectName: args.projectName,
|
|
515
|
+
section: args.section,
|
|
516
|
+
subSection: args.subSection || null,
|
|
517
|
+
title: args.title,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
case 'devplan_get_section': {
|
|
521
|
+
if (!args.projectName || !args.section) {
|
|
522
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, section');
|
|
523
|
+
}
|
|
524
|
+
const plan = getDevPlan(args.projectName);
|
|
525
|
+
const doc = plan.getSection(args.section, args.subSection);
|
|
526
|
+
if (!doc) {
|
|
527
|
+
return JSON.stringify({
|
|
528
|
+
found: false,
|
|
529
|
+
message: `Section "${args.section}"${args.subSection ? ` (${args.subSection})` : ''} not found for project "${args.projectName}"`,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
return JSON.stringify({
|
|
533
|
+
found: true,
|
|
534
|
+
document: doc,
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
case 'devplan_list_sections': {
|
|
538
|
+
if (!args.projectName) {
|
|
539
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
540
|
+
}
|
|
541
|
+
const plan = getDevPlan(args.projectName);
|
|
542
|
+
const sections = plan.listSections();
|
|
543
|
+
return JSON.stringify({
|
|
544
|
+
projectName: args.projectName,
|
|
545
|
+
count: sections.length,
|
|
546
|
+
sections: sections.map(s => ({
|
|
547
|
+
id: s.id,
|
|
548
|
+
section: s.section,
|
|
549
|
+
subSection: s.subSection || null,
|
|
550
|
+
title: s.title,
|
|
551
|
+
version: s.version,
|
|
552
|
+
contentPreview: s.content.slice(0, 200) + (s.content.length > 200 ? '...' : ''),
|
|
553
|
+
updatedAt: s.updatedAt,
|
|
554
|
+
})),
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
case 'devplan_create_main_task': {
|
|
558
|
+
if (!args.projectName || !args.taskId || !args.title || !args.priority) {
|
|
559
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, taskId, title, priority');
|
|
560
|
+
}
|
|
561
|
+
const plan = getDevPlan(args.projectName);
|
|
562
|
+
try {
|
|
563
|
+
const mainTask = plan.createMainTask({
|
|
564
|
+
projectName: args.projectName,
|
|
565
|
+
taskId: args.taskId,
|
|
566
|
+
title: args.title,
|
|
567
|
+
priority: args.priority,
|
|
568
|
+
description: args.description,
|
|
569
|
+
estimatedHours: args.estimatedHours,
|
|
570
|
+
moduleId: args.moduleId,
|
|
571
|
+
});
|
|
572
|
+
return JSON.stringify({
|
|
573
|
+
success: true,
|
|
574
|
+
mainTask: {
|
|
575
|
+
id: mainTask.id,
|
|
576
|
+
taskId: mainTask.taskId,
|
|
577
|
+
title: mainTask.title,
|
|
578
|
+
priority: mainTask.priority,
|
|
579
|
+
status: mainTask.status,
|
|
580
|
+
},
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
catch (err) {
|
|
584
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, err instanceof Error ? err.message : String(err));
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
case 'devplan_add_sub_task': {
|
|
588
|
+
if (!args.projectName || !args.taskId || !args.parentTaskId || !args.title) {
|
|
589
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, taskId, parentTaskId, title');
|
|
590
|
+
}
|
|
591
|
+
const plan = getDevPlan(args.projectName);
|
|
592
|
+
try {
|
|
593
|
+
const subTask = plan.addSubTask({
|
|
594
|
+
projectName: args.projectName,
|
|
595
|
+
taskId: args.taskId,
|
|
596
|
+
parentTaskId: args.parentTaskId,
|
|
597
|
+
title: args.title,
|
|
598
|
+
estimatedHours: args.estimatedHours,
|
|
599
|
+
description: args.description,
|
|
600
|
+
});
|
|
601
|
+
return JSON.stringify({
|
|
602
|
+
success: true,
|
|
603
|
+
subTask: {
|
|
604
|
+
id: subTask.id,
|
|
605
|
+
taskId: subTask.taskId,
|
|
606
|
+
parentTaskId: subTask.parentTaskId,
|
|
607
|
+
title: subTask.title,
|
|
608
|
+
status: subTask.status,
|
|
609
|
+
},
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
catch (err) {
|
|
613
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, err instanceof Error ? err.message : String(err));
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
case 'devplan_upsert_task': {
|
|
617
|
+
if (!args.projectName || !args.taskType || !args.taskId || !args.title) {
|
|
618
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, taskType, taskId, title');
|
|
619
|
+
}
|
|
620
|
+
const plan = getDevPlan(args.projectName);
|
|
621
|
+
const upsertTaskType = args.taskType;
|
|
622
|
+
const targetStatus = args.status || 'pending';
|
|
623
|
+
const preserveStatus = args.preserveStatus !== false; // 默认 true
|
|
624
|
+
try {
|
|
625
|
+
if (upsertTaskType === 'main') {
|
|
626
|
+
if (!args.priority) {
|
|
627
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required for main task: priority');
|
|
628
|
+
}
|
|
629
|
+
const mainTask = plan.upsertMainTask({
|
|
630
|
+
projectName: args.projectName,
|
|
631
|
+
taskId: args.taskId,
|
|
632
|
+
title: args.title,
|
|
633
|
+
priority: args.priority,
|
|
634
|
+
description: args.description,
|
|
635
|
+
estimatedHours: args.estimatedHours,
|
|
636
|
+
moduleId: args.moduleId,
|
|
637
|
+
}, { preserveStatus, status: targetStatus });
|
|
638
|
+
return JSON.stringify({
|
|
639
|
+
success: true,
|
|
640
|
+
taskType: 'main',
|
|
641
|
+
mainTask: {
|
|
642
|
+
id: mainTask.id,
|
|
643
|
+
taskId: mainTask.taskId,
|
|
644
|
+
title: mainTask.title,
|
|
645
|
+
priority: mainTask.priority,
|
|
646
|
+
status: mainTask.status,
|
|
647
|
+
updatedAt: mainTask.updatedAt,
|
|
648
|
+
},
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
if (!args.parentTaskId) {
|
|
653
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required for sub-task: parentTaskId');
|
|
654
|
+
}
|
|
655
|
+
const subTask = plan.upsertSubTask({
|
|
656
|
+
projectName: args.projectName,
|
|
657
|
+
taskId: args.taskId,
|
|
658
|
+
parentTaskId: args.parentTaskId,
|
|
659
|
+
title: args.title,
|
|
660
|
+
estimatedHours: args.estimatedHours,
|
|
661
|
+
description: args.description,
|
|
662
|
+
}, { preserveStatus, status: targetStatus });
|
|
663
|
+
return JSON.stringify({
|
|
664
|
+
success: true,
|
|
665
|
+
taskType: 'sub',
|
|
666
|
+
subTask: {
|
|
667
|
+
id: subTask.id,
|
|
668
|
+
taskId: subTask.taskId,
|
|
669
|
+
parentTaskId: subTask.parentTaskId,
|
|
670
|
+
title: subTask.title,
|
|
671
|
+
status: subTask.status,
|
|
672
|
+
updatedAt: subTask.updatedAt,
|
|
673
|
+
},
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
catch (err) {
|
|
678
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, err instanceof Error ? err.message : String(err));
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
case 'devplan_complete_task': {
|
|
682
|
+
if (!args.projectName || !args.taskId) {
|
|
683
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, taskId');
|
|
684
|
+
}
|
|
685
|
+
const plan = getDevPlan(args.projectName);
|
|
686
|
+
const taskType = args.taskType || 'sub';
|
|
687
|
+
try {
|
|
688
|
+
if (taskType === 'main') {
|
|
689
|
+
const mainTask = plan.completeMainTask(args.taskId);
|
|
690
|
+
return JSON.stringify({
|
|
691
|
+
success: true,
|
|
692
|
+
taskType: 'main',
|
|
693
|
+
mainTask: {
|
|
694
|
+
taskId: mainTask.taskId,
|
|
695
|
+
title: mainTask.title,
|
|
696
|
+
status: mainTask.status,
|
|
697
|
+
completedAt: mainTask.completedAt,
|
|
698
|
+
totalSubtasks: mainTask.totalSubtasks,
|
|
699
|
+
completedSubtasks: mainTask.completedSubtasks,
|
|
700
|
+
},
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
else {
|
|
704
|
+
const result = plan.completeSubTask(args.taskId);
|
|
705
|
+
return JSON.stringify({
|
|
706
|
+
success: true,
|
|
707
|
+
taskType: 'sub',
|
|
708
|
+
subTask: {
|
|
709
|
+
taskId: result.subTask.taskId,
|
|
710
|
+
title: result.subTask.title,
|
|
711
|
+
status: result.subTask.status,
|
|
712
|
+
completedAt: result.subTask.completedAt,
|
|
713
|
+
completedAtCommit: result.completedAtCommit || null,
|
|
714
|
+
},
|
|
715
|
+
mainTask: {
|
|
716
|
+
taskId: result.mainTask.taskId,
|
|
717
|
+
title: result.mainTask.title,
|
|
718
|
+
status: result.mainTask.status,
|
|
719
|
+
totalSubtasks: result.mainTask.totalSubtasks,
|
|
720
|
+
completedSubtasks: result.mainTask.completedSubtasks,
|
|
721
|
+
},
|
|
722
|
+
mainTaskCompleted: result.mainTaskCompleted,
|
|
723
|
+
completedAtCommit: result.completedAtCommit || null,
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
catch (err) {
|
|
728
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, err instanceof Error ? err.message : String(err));
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
case 'devplan_list_tasks': {
|
|
732
|
+
if (!args.projectName) {
|
|
733
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
734
|
+
}
|
|
735
|
+
const plan = getDevPlan(args.projectName);
|
|
736
|
+
if (args.parentTaskId) {
|
|
737
|
+
// Mode 1: List sub-tasks of a specific main task
|
|
738
|
+
const subTasks = plan.listSubTasks(args.parentTaskId, {
|
|
739
|
+
status: args.status,
|
|
740
|
+
});
|
|
741
|
+
return JSON.stringify({
|
|
742
|
+
projectName: args.projectName,
|
|
743
|
+
parentTaskId: args.parentTaskId,
|
|
744
|
+
count: subTasks.length,
|
|
745
|
+
subTasks: subTasks.map(st => ({
|
|
746
|
+
taskId: st.taskId,
|
|
747
|
+
title: st.title,
|
|
748
|
+
status: st.status,
|
|
749
|
+
estimatedHours: st.estimatedHours,
|
|
750
|
+
completedAt: st.completedAt,
|
|
751
|
+
})),
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
else if (args.status && !args.priority && !args.moduleId) {
|
|
755
|
+
// Mode 2: Aggregate sub-tasks across ALL main tasks matching the status filter
|
|
756
|
+
const mainTasks = plan.listMainTasks();
|
|
757
|
+
const allSubTasks = [];
|
|
758
|
+
for (const mt of mainTasks) {
|
|
759
|
+
const subs = plan.listSubTasks(mt.taskId, {
|
|
760
|
+
status: args.status,
|
|
761
|
+
});
|
|
762
|
+
for (const sub of subs) {
|
|
763
|
+
allSubTasks.push({
|
|
764
|
+
taskId: sub.taskId,
|
|
765
|
+
title: sub.title,
|
|
766
|
+
status: sub.status,
|
|
767
|
+
estimatedHours: sub.estimatedHours,
|
|
768
|
+
completedAt: sub.completedAt,
|
|
769
|
+
parentTaskId: mt.taskId,
|
|
770
|
+
parentTitle: mt.title,
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return JSON.stringify({
|
|
775
|
+
projectName: args.projectName,
|
|
776
|
+
status: args.status,
|
|
777
|
+
count: allSubTasks.length,
|
|
778
|
+
subTasks: allSubTasks,
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
else {
|
|
782
|
+
// Mode 3: List main tasks (supports moduleId filter)
|
|
783
|
+
const mainTasks = plan.listMainTasks({
|
|
784
|
+
status: args.status,
|
|
785
|
+
priority: args.priority,
|
|
786
|
+
moduleId: args.moduleId,
|
|
787
|
+
});
|
|
788
|
+
return JSON.stringify({
|
|
789
|
+
projectName: args.projectName,
|
|
790
|
+
count: mainTasks.length,
|
|
791
|
+
mainTasks: mainTasks.map(mt => ({
|
|
792
|
+
taskId: mt.taskId,
|
|
793
|
+
title: mt.title,
|
|
794
|
+
priority: mt.priority,
|
|
795
|
+
status: mt.status,
|
|
796
|
+
totalSubtasks: mt.totalSubtasks,
|
|
797
|
+
completedSubtasks: mt.completedSubtasks,
|
|
798
|
+
estimatedHours: mt.estimatedHours,
|
|
799
|
+
completedAt: mt.completedAt,
|
|
800
|
+
})),
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
case 'devplan_get_progress': {
|
|
805
|
+
if (!args.projectName) {
|
|
806
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
807
|
+
}
|
|
808
|
+
const plan = getDevPlan(args.projectName);
|
|
809
|
+
const progress = plan.getProgress();
|
|
810
|
+
return JSON.stringify(progress);
|
|
811
|
+
}
|
|
812
|
+
case 'devplan_export_markdown': {
|
|
813
|
+
if (!args.projectName) {
|
|
814
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
815
|
+
}
|
|
816
|
+
const plan = getDevPlan(args.projectName);
|
|
817
|
+
const scope = args.scope || 'tasks';
|
|
818
|
+
const markdown = scope === 'full'
|
|
819
|
+
? plan.exportToMarkdown()
|
|
820
|
+
: plan.exportTaskSummary();
|
|
821
|
+
return JSON.stringify({
|
|
822
|
+
projectName: args.projectName,
|
|
823
|
+
scope,
|
|
824
|
+
markdown,
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
case 'devplan_sync_git': {
|
|
828
|
+
if (!args.projectName) {
|
|
829
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
830
|
+
}
|
|
831
|
+
const plan = getDevPlan(args.projectName);
|
|
832
|
+
const dryRun = args.dryRun ?? false;
|
|
833
|
+
try {
|
|
834
|
+
const result = plan.syncWithGit(dryRun);
|
|
835
|
+
return JSON.stringify({
|
|
836
|
+
success: true,
|
|
837
|
+
dryRun,
|
|
838
|
+
...result,
|
|
839
|
+
summary: result.error
|
|
840
|
+
? `⚠️ ${result.error}`
|
|
841
|
+
: result.reverted.length === 0
|
|
842
|
+
? `✅ All ${result.checked} completed tasks are consistent with Git HEAD (${result.currentHead})`
|
|
843
|
+
: dryRun
|
|
844
|
+
? `⚠️ ${result.reverted.length} of ${result.checked} tasks would be reverted (dry run, no changes made)`
|
|
845
|
+
: `🔄 ${result.reverted.length} of ${result.checked} tasks reverted to pending due to Git rollback`,
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
catch (err) {
|
|
849
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, err instanceof Error ? err.message : String(err));
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
case 'devplan_create_module': {
|
|
853
|
+
if (!args.projectName || !args.moduleId || !args.name) {
|
|
854
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, moduleId, name');
|
|
855
|
+
}
|
|
856
|
+
const plan = getDevPlan(args.projectName);
|
|
857
|
+
try {
|
|
858
|
+
const mod = plan.createModule({
|
|
859
|
+
projectName: args.projectName,
|
|
860
|
+
moduleId: args.moduleId,
|
|
861
|
+
name: args.name,
|
|
862
|
+
description: args.description,
|
|
863
|
+
status: args.status,
|
|
864
|
+
});
|
|
865
|
+
return JSON.stringify({ success: true, module: mod });
|
|
866
|
+
}
|
|
867
|
+
catch (err) {
|
|
868
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, err instanceof Error ? err.message : String(err));
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
case 'devplan_list_modules': {
|
|
872
|
+
if (!args.projectName) {
|
|
873
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName');
|
|
874
|
+
}
|
|
875
|
+
const plan = getDevPlan(args.projectName);
|
|
876
|
+
const modules = plan.listModules({
|
|
877
|
+
status: args.status,
|
|
878
|
+
});
|
|
879
|
+
return JSON.stringify({
|
|
880
|
+
projectName: args.projectName,
|
|
881
|
+
count: modules.length,
|
|
882
|
+
modules: modules.map(m => ({
|
|
883
|
+
moduleId: m.moduleId,
|
|
884
|
+
name: m.name,
|
|
885
|
+
description: m.description,
|
|
886
|
+
status: m.status,
|
|
887
|
+
mainTaskCount: m.mainTaskCount,
|
|
888
|
+
subTaskCount: m.subTaskCount,
|
|
889
|
+
completedSubTaskCount: m.completedSubTaskCount,
|
|
890
|
+
docCount: m.docCount,
|
|
891
|
+
createdAt: m.createdAt,
|
|
892
|
+
updatedAt: m.updatedAt,
|
|
893
|
+
})),
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
case 'devplan_get_module': {
|
|
897
|
+
if (!args.projectName || !args.moduleId) {
|
|
898
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, moduleId');
|
|
899
|
+
}
|
|
900
|
+
const plan = getDevPlan(args.projectName);
|
|
901
|
+
const detail = plan.getModuleDetail(args.moduleId);
|
|
902
|
+
if (!detail) {
|
|
903
|
+
return JSON.stringify({ error: `Module "${args.moduleId}" not found` });
|
|
904
|
+
}
|
|
905
|
+
return JSON.stringify({
|
|
906
|
+
projectName: args.projectName,
|
|
907
|
+
module: {
|
|
908
|
+
moduleId: detail.module.moduleId,
|
|
909
|
+
name: detail.module.name,
|
|
910
|
+
description: detail.module.description,
|
|
911
|
+
status: detail.module.status,
|
|
912
|
+
mainTaskCount: detail.module.mainTaskCount,
|
|
913
|
+
subTaskCount: detail.module.subTaskCount,
|
|
914
|
+
completedSubTaskCount: detail.module.completedSubTaskCount,
|
|
915
|
+
docCount: detail.module.docCount,
|
|
916
|
+
},
|
|
917
|
+
mainTasks: detail.mainTasks.map(mt => ({
|
|
918
|
+
taskId: mt.taskId,
|
|
919
|
+
title: mt.title,
|
|
920
|
+
priority: mt.priority,
|
|
921
|
+
status: mt.status,
|
|
922
|
+
totalSubtasks: mt.totalSubtasks,
|
|
923
|
+
completedSubtasks: mt.completedSubtasks,
|
|
924
|
+
})),
|
|
925
|
+
subTasks: detail.subTasks.map(st => ({
|
|
926
|
+
taskId: st.taskId,
|
|
927
|
+
title: st.title,
|
|
928
|
+
status: st.status,
|
|
929
|
+
parentTaskId: st.parentTaskId,
|
|
930
|
+
})),
|
|
931
|
+
documents: detail.documents.map(doc => ({
|
|
932
|
+
section: doc.section,
|
|
933
|
+
subSection: doc.subSection,
|
|
934
|
+
title: doc.title,
|
|
935
|
+
})),
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
case 'devplan_update_module': {
|
|
939
|
+
if (!args.projectName || !args.moduleId) {
|
|
940
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing required: projectName, moduleId');
|
|
941
|
+
}
|
|
942
|
+
const plan = getDevPlan(args.projectName);
|
|
943
|
+
const updated = plan.updateModule(args.moduleId, {
|
|
944
|
+
name: args.name,
|
|
945
|
+
description: args.description,
|
|
946
|
+
status: args.status,
|
|
947
|
+
});
|
|
948
|
+
if (!updated) {
|
|
949
|
+
return JSON.stringify({ error: `Module "${args.moduleId}" not found` });
|
|
950
|
+
}
|
|
951
|
+
return JSON.stringify({ success: true, module: updated });
|
|
952
|
+
}
|
|
953
|
+
default:
|
|
954
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
// ============================================================================
|
|
958
|
+
// Server Setup
|
|
959
|
+
// ============================================================================
|
|
960
|
+
async function main() {
|
|
961
|
+
const server = new index_js_1.Server({
|
|
962
|
+
name: 'aifastdb-devplan',
|
|
963
|
+
version: '1.0.0',
|
|
964
|
+
}, {
|
|
965
|
+
capabilities: {
|
|
966
|
+
tools: {},
|
|
967
|
+
},
|
|
968
|
+
});
|
|
969
|
+
// List tools handler
|
|
970
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
971
|
+
tools: TOOLS,
|
|
972
|
+
}));
|
|
973
|
+
// Call tool handler
|
|
974
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
975
|
+
const { name, arguments: args } = request.params;
|
|
976
|
+
try {
|
|
977
|
+
const result = await handleToolCall(name, args);
|
|
978
|
+
return {
|
|
979
|
+
content: [
|
|
980
|
+
{
|
|
981
|
+
type: 'text',
|
|
982
|
+
text: result,
|
|
983
|
+
},
|
|
984
|
+
],
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
catch (error) {
|
|
988
|
+
if (error instanceof types_js_1.McpError) {
|
|
989
|
+
throw error;
|
|
990
|
+
}
|
|
991
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Error executing ${name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
992
|
+
}
|
|
993
|
+
});
|
|
994
|
+
// Start server
|
|
995
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
996
|
+
await server.connect(transport);
|
|
997
|
+
console.error('aifastdb-devplan MCP Server started');
|
|
998
|
+
}
|
|
999
|
+
// Run
|
|
1000
|
+
main().catch((error) => {
|
|
1001
|
+
console.error('Failed to start MCP server:', error);
|
|
1002
|
+
process.exit(1);
|
|
1003
|
+
});
|
|
1004
|
+
//# sourceMappingURL=index.js.map
|