@allpepper/task-orchestrator 0.1.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/README.md +15 -0
- package/package.json +51 -0
- package/src/db/client.ts +34 -0
- package/src/db/index.ts +1 -0
- package/src/db/migrate.ts +51 -0
- package/src/db/migrations/001_initial_schema.sql +160 -0
- package/src/domain/index.ts +1 -0
- package/src/domain/types.ts +225 -0
- package/src/index.ts +7 -0
- package/src/repos/base.ts +151 -0
- package/src/repos/dependencies.ts +356 -0
- package/src/repos/features.ts +507 -0
- package/src/repos/index.ts +4 -0
- package/src/repos/projects.ts +350 -0
- package/src/repos/sections.ts +505 -0
- package/src/repos/tags.example.ts +125 -0
- package/src/repos/tags.ts +175 -0
- package/src/repos/tasks.ts +581 -0
- package/src/repos/templates.ts +649 -0
- package/src/server.ts +121 -0
- package/src/services/index.ts +2 -0
- package/src/services/status-validator.ts +100 -0
- package/src/services/workflow.ts +104 -0
- package/src/tools/apply-template.ts +129 -0
- package/src/tools/get-blocked-tasks.ts +63 -0
- package/src/tools/get-next-status.ts +183 -0
- package/src/tools/get-next-task.ts +75 -0
- package/src/tools/get-tag-usage.ts +54 -0
- package/src/tools/index.ts +30 -0
- package/src/tools/list-tags.ts +56 -0
- package/src/tools/manage-container.ts +333 -0
- package/src/tools/manage-dependency.ts +198 -0
- package/src/tools/manage-sections.ts +388 -0
- package/src/tools/manage-template.ts +313 -0
- package/src/tools/query-container.ts +296 -0
- package/src/tools/query-dependencies.ts +68 -0
- package/src/tools/query-sections.ts +70 -0
- package/src/tools/query-templates.ts +137 -0
- package/src/tools/query-workflow-state.ts +198 -0
- package/src/tools/registry.ts +180 -0
- package/src/tools/rename-tag.ts +64 -0
- package/src/tools/setup-project.ts +189 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { createSuccessResponse, createErrorResponse, uuidSchema, optionalUuidSchema } from './registry';
|
|
4
|
+
import {
|
|
5
|
+
addSection,
|
|
6
|
+
updateSection,
|
|
7
|
+
updateSectionText,
|
|
8
|
+
deleteSection,
|
|
9
|
+
reorderSections,
|
|
10
|
+
bulkCreateSections,
|
|
11
|
+
bulkDeleteSections
|
|
12
|
+
} from '../repos/sections';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Register the manage_sections MCP tool
|
|
16
|
+
*
|
|
17
|
+
* Provides comprehensive section management with operations: add, update, updateText, delete, reorder, bulkCreate, bulkDelete.
|
|
18
|
+
*/
|
|
19
|
+
export function registerManageSectionsTool(server: McpServer): void {
|
|
20
|
+
server.tool(
|
|
21
|
+
'manage_sections',
|
|
22
|
+
'Manage sections with operations: add (create new), update (modify fields), updateText (update content only), delete (remove), reorder (change ordinals), bulkCreate (create multiple), bulkDelete (remove multiple).',
|
|
23
|
+
{
|
|
24
|
+
operation: z.enum(['add', 'update', 'updateText', 'delete', 'reorder', 'bulkCreate', 'bulkDelete']).describe('The operation to perform'),
|
|
25
|
+
entityType: z.enum(['PROJECT', 'FEATURE', 'TASK']).optional().describe('Required for: add, bulkCreate'),
|
|
26
|
+
entityId: optionalUuidSchema.describe('Required for: add, reorder, bulkCreate'),
|
|
27
|
+
sectionId: optionalUuidSchema.describe('Required for: update, updateText, delete'),
|
|
28
|
+
title: z.string().optional().describe('Section title (for add/update)'),
|
|
29
|
+
usageDescription: z.string().optional().describe('Description of how to use this section (for add/update)'),
|
|
30
|
+
content: z.string().optional().describe('Section content (for add/update/updateText)'),
|
|
31
|
+
contentFormat: z.enum(['PLAIN_TEXT', 'MARKDOWN', 'JSON', 'CODE']).optional().describe('Content format (for add/update)'),
|
|
32
|
+
tags: z.string().optional().describe('Comma-separated tags (for add/update)'),
|
|
33
|
+
ordinal: z.number().int().optional().describe('Display order (for add)'),
|
|
34
|
+
version: z.number().int().optional().describe('Required for: update, updateText (for optimistic locking)'),
|
|
35
|
+
orderedIds: z.string().optional().describe('Comma-separated section IDs in new order (for reorder)'),
|
|
36
|
+
sections: z.string().optional().describe('JSON array of sections to create (for bulkCreate)'),
|
|
37
|
+
sectionIds: z.string().optional().describe('Comma-separated section IDs to delete (for bulkDelete)')
|
|
38
|
+
},
|
|
39
|
+
async (params) => {
|
|
40
|
+
try {
|
|
41
|
+
switch (params.operation) {
|
|
42
|
+
case 'add': {
|
|
43
|
+
// Validate required parameters
|
|
44
|
+
if (!params.entityType || !params.entityId || !params.title || !params.usageDescription || !params.content) {
|
|
45
|
+
return {
|
|
46
|
+
content: [{
|
|
47
|
+
type: 'text' as const,
|
|
48
|
+
text: JSON.stringify(
|
|
49
|
+
createErrorResponse('Missing required parameters for add: entityType, entityId, title, usageDescription, content'),
|
|
50
|
+
null,
|
|
51
|
+
2
|
|
52
|
+
)
|
|
53
|
+
}]
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const result = addSection({
|
|
58
|
+
entityType: params.entityType,
|
|
59
|
+
entityId: params.entityId,
|
|
60
|
+
title: params.title,
|
|
61
|
+
usageDescription: params.usageDescription,
|
|
62
|
+
content: params.content,
|
|
63
|
+
contentFormat: params.contentFormat,
|
|
64
|
+
ordinal: params.ordinal,
|
|
65
|
+
tags: params.tags
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (!result.success) {
|
|
69
|
+
return {
|
|
70
|
+
content: [{
|
|
71
|
+
type: 'text' as const,
|
|
72
|
+
text: JSON.stringify(createErrorResponse(result.error), null, 2)
|
|
73
|
+
}]
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
content: [{
|
|
79
|
+
type: 'text' as const,
|
|
80
|
+
text: JSON.stringify(
|
|
81
|
+
createSuccessResponse('Section added successfully', result.data),
|
|
82
|
+
null,
|
|
83
|
+
2
|
|
84
|
+
)
|
|
85
|
+
}]
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
case 'update': {
|
|
90
|
+
// Validate required parameters
|
|
91
|
+
if (!params.sectionId || params.version === undefined) {
|
|
92
|
+
return {
|
|
93
|
+
content: [{
|
|
94
|
+
type: 'text' as const,
|
|
95
|
+
text: JSON.stringify(
|
|
96
|
+
createErrorResponse('Missing required parameters for update: sectionId, version'),
|
|
97
|
+
null,
|
|
98
|
+
2
|
|
99
|
+
)
|
|
100
|
+
}]
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const result = updateSection(params.sectionId, {
|
|
105
|
+
title: params.title,
|
|
106
|
+
usageDescription: params.usageDescription,
|
|
107
|
+
content: params.content,
|
|
108
|
+
contentFormat: params.contentFormat,
|
|
109
|
+
tags: params.tags,
|
|
110
|
+
version: params.version
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (!result.success) {
|
|
114
|
+
return {
|
|
115
|
+
content: [{
|
|
116
|
+
type: 'text' as const,
|
|
117
|
+
text: JSON.stringify(createErrorResponse(result.error), null, 2)
|
|
118
|
+
}]
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
content: [{
|
|
124
|
+
type: 'text' as const,
|
|
125
|
+
text: JSON.stringify(
|
|
126
|
+
createSuccessResponse('Section updated successfully', result.data),
|
|
127
|
+
null,
|
|
128
|
+
2
|
|
129
|
+
)
|
|
130
|
+
}]
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
case 'updateText': {
|
|
135
|
+
// Validate required parameters
|
|
136
|
+
if (!params.sectionId || !params.content || params.version === undefined) {
|
|
137
|
+
return {
|
|
138
|
+
content: [{
|
|
139
|
+
type: 'text' as const,
|
|
140
|
+
text: JSON.stringify(
|
|
141
|
+
createErrorResponse('Missing required parameters for updateText: sectionId, content, version'),
|
|
142
|
+
null,
|
|
143
|
+
2
|
|
144
|
+
)
|
|
145
|
+
}]
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const result = updateSectionText(params.sectionId, params.content, params.version);
|
|
150
|
+
|
|
151
|
+
if (!result.success) {
|
|
152
|
+
return {
|
|
153
|
+
content: [{
|
|
154
|
+
type: 'text' as const,
|
|
155
|
+
text: JSON.stringify(createErrorResponse(result.error), null, 2)
|
|
156
|
+
}]
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
content: [{
|
|
162
|
+
type: 'text' as const,
|
|
163
|
+
text: JSON.stringify(
|
|
164
|
+
createSuccessResponse('Section text updated successfully', result.data),
|
|
165
|
+
null,
|
|
166
|
+
2
|
|
167
|
+
)
|
|
168
|
+
}]
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
case 'delete': {
|
|
173
|
+
// Validate required parameters
|
|
174
|
+
if (!params.sectionId) {
|
|
175
|
+
return {
|
|
176
|
+
content: [{
|
|
177
|
+
type: 'text' as const,
|
|
178
|
+
text: JSON.stringify(
|
|
179
|
+
createErrorResponse('Missing required parameter for delete: sectionId'),
|
|
180
|
+
null,
|
|
181
|
+
2
|
|
182
|
+
)
|
|
183
|
+
}]
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const result = deleteSection(params.sectionId);
|
|
188
|
+
|
|
189
|
+
if (!result.success) {
|
|
190
|
+
return {
|
|
191
|
+
content: [{
|
|
192
|
+
type: 'text' as const,
|
|
193
|
+
text: JSON.stringify(createErrorResponse(result.error), null, 2)
|
|
194
|
+
}]
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
content: [{
|
|
200
|
+
type: 'text' as const,
|
|
201
|
+
text: JSON.stringify(
|
|
202
|
+
createSuccessResponse('Section deleted successfully', { deleted: result.data }),
|
|
203
|
+
null,
|
|
204
|
+
2
|
|
205
|
+
)
|
|
206
|
+
}]
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
case 'reorder': {
|
|
211
|
+
// Validate required parameters
|
|
212
|
+
if (!params.entityId || !params.entityType || !params.orderedIds) {
|
|
213
|
+
return {
|
|
214
|
+
content: [{
|
|
215
|
+
type: 'text' as const,
|
|
216
|
+
text: JSON.stringify(
|
|
217
|
+
createErrorResponse('Missing required parameters for reorder: entityId, entityType, orderedIds'),
|
|
218
|
+
null,
|
|
219
|
+
2
|
|
220
|
+
)
|
|
221
|
+
}]
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const orderedIds = params.orderedIds.split(',').map(id => id.trim().replace(/-/g, ''));
|
|
226
|
+
const result = reorderSections(params.entityId, params.entityType, orderedIds);
|
|
227
|
+
|
|
228
|
+
if (!result.success) {
|
|
229
|
+
return {
|
|
230
|
+
content: [{
|
|
231
|
+
type: 'text' as const,
|
|
232
|
+
text: JSON.stringify(createErrorResponse(result.error), null, 2)
|
|
233
|
+
}]
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
content: [{
|
|
239
|
+
type: 'text' as const,
|
|
240
|
+
text: JSON.stringify(
|
|
241
|
+
createSuccessResponse('Sections reordered successfully', { reordered: result.data }),
|
|
242
|
+
null,
|
|
243
|
+
2
|
|
244
|
+
)
|
|
245
|
+
}]
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
case 'bulkCreate': {
|
|
250
|
+
// Validate required parameters
|
|
251
|
+
if (!params.sections) {
|
|
252
|
+
return {
|
|
253
|
+
content: [{
|
|
254
|
+
type: 'text' as const,
|
|
255
|
+
text: JSON.stringify(
|
|
256
|
+
createErrorResponse('Missing required parameter for bulkCreate: sections (JSON array string)'),
|
|
257
|
+
null,
|
|
258
|
+
2
|
|
259
|
+
)
|
|
260
|
+
}]
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (!params.entityType || !params.entityId) {
|
|
265
|
+
return {
|
|
266
|
+
content: [{
|
|
267
|
+
type: 'text' as const,
|
|
268
|
+
text: JSON.stringify(
|
|
269
|
+
createErrorResponse('Missing required parameters for bulkCreate: entityType, entityId'),
|
|
270
|
+
null,
|
|
271
|
+
2
|
|
272
|
+
)
|
|
273
|
+
}]
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
let sectionsArray;
|
|
278
|
+
try {
|
|
279
|
+
sectionsArray = JSON.parse(params.sections);
|
|
280
|
+
} catch (error) {
|
|
281
|
+
return {
|
|
282
|
+
content: [{
|
|
283
|
+
type: 'text' as const,
|
|
284
|
+
text: JSON.stringify(
|
|
285
|
+
createErrorResponse('Invalid JSON format for sections parameter'),
|
|
286
|
+
null,
|
|
287
|
+
2
|
|
288
|
+
)
|
|
289
|
+
}]
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Inject entityType and entityId from top-level params into each section
|
|
294
|
+
const enrichedSections = sectionsArray.map((section: any) => ({
|
|
295
|
+
...section,
|
|
296
|
+
entityType: params.entityType,
|
|
297
|
+
entityId: params.entityId,
|
|
298
|
+
}));
|
|
299
|
+
|
|
300
|
+
const result = bulkCreateSections(enrichedSections);
|
|
301
|
+
|
|
302
|
+
if (!result.success) {
|
|
303
|
+
return {
|
|
304
|
+
content: [{
|
|
305
|
+
type: 'text' as const,
|
|
306
|
+
text: JSON.stringify(createErrorResponse(result.error), null, 2)
|
|
307
|
+
}]
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return {
|
|
312
|
+
content: [{
|
|
313
|
+
type: 'text' as const,
|
|
314
|
+
text: JSON.stringify(
|
|
315
|
+
createSuccessResponse('Sections bulk created successfully', result.data),
|
|
316
|
+
null,
|
|
317
|
+
2
|
|
318
|
+
)
|
|
319
|
+
}]
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
case 'bulkDelete': {
|
|
324
|
+
// Validate required parameters
|
|
325
|
+
if (!params.sectionIds) {
|
|
326
|
+
return {
|
|
327
|
+
content: [{
|
|
328
|
+
type: 'text' as const,
|
|
329
|
+
text: JSON.stringify(
|
|
330
|
+
createErrorResponse('Missing required parameter for bulkDelete: sectionIds'),
|
|
331
|
+
null,
|
|
332
|
+
2
|
|
333
|
+
)
|
|
334
|
+
}]
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const sectionIds = params.sectionIds.split(',').map(id => id.trim().replace(/-/g, ''));
|
|
339
|
+
const result = bulkDeleteSections(sectionIds);
|
|
340
|
+
|
|
341
|
+
if (!result.success) {
|
|
342
|
+
return {
|
|
343
|
+
content: [{
|
|
344
|
+
type: 'text' as const,
|
|
345
|
+
text: JSON.stringify(createErrorResponse(result.error), null, 2)
|
|
346
|
+
}]
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
content: [{
|
|
352
|
+
type: 'text' as const,
|
|
353
|
+
text: JSON.stringify(
|
|
354
|
+
createSuccessResponse('Sections bulk deleted successfully', { deletedCount: result.data }),
|
|
355
|
+
null,
|
|
356
|
+
2
|
|
357
|
+
)
|
|
358
|
+
}]
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
default:
|
|
363
|
+
return {
|
|
364
|
+
content: [{
|
|
365
|
+
type: 'text' as const,
|
|
366
|
+
text: JSON.stringify(
|
|
367
|
+
createErrorResponse(`Invalid operation: ${params.operation}`),
|
|
368
|
+
null,
|
|
369
|
+
2
|
|
370
|
+
)
|
|
371
|
+
}]
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
} catch (error: any) {
|
|
375
|
+
return {
|
|
376
|
+
content: [{
|
|
377
|
+
type: 'text' as const,
|
|
378
|
+
text: JSON.stringify(
|
|
379
|
+
createErrorResponse(error.message || 'Failed to manage section'),
|
|
380
|
+
null,
|
|
381
|
+
2
|
|
382
|
+
)
|
|
383
|
+
}]
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
);
|
|
388
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { createSuccessResponse, createErrorResponse, uuidSchema, optionalUuidSchema } from './registry';
|
|
4
|
+
import {
|
|
5
|
+
createTemplate,
|
|
6
|
+
updateTemplate,
|
|
7
|
+
deleteTemplate,
|
|
8
|
+
enableTemplate,
|
|
9
|
+
disableTemplate,
|
|
10
|
+
addTemplateSection
|
|
11
|
+
} from '../repos/templates';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Registers the `manage_template` MCP tool.
|
|
15
|
+
*
|
|
16
|
+
* Operations:
|
|
17
|
+
* - create: Create a new template
|
|
18
|
+
* - update: Update an existing template
|
|
19
|
+
* - delete: Delete a template
|
|
20
|
+
* - enable: Enable a template
|
|
21
|
+
* - disable: Disable a template
|
|
22
|
+
* - addSection: Add a section to a template
|
|
23
|
+
*/
|
|
24
|
+
export function registerManageTemplateTool(server: McpServer): void {
|
|
25
|
+
server.tool(
|
|
26
|
+
'manage_template',
|
|
27
|
+
'Manage templates with operations: create, update, delete, enable, disable, or addSection',
|
|
28
|
+
{
|
|
29
|
+
operation: z.enum(['create', 'update', 'delete', 'enable', 'disable', 'addSection']),
|
|
30
|
+
id: optionalUuidSchema,
|
|
31
|
+
name: z.string().optional(),
|
|
32
|
+
description: z.string().optional(),
|
|
33
|
+
targetEntityType: z.string().optional(),
|
|
34
|
+
isBuiltIn: z.boolean().optional(),
|
|
35
|
+
isProtected: z.boolean().optional(),
|
|
36
|
+
createdBy: z.string().optional(),
|
|
37
|
+
tags: z.string().optional(),
|
|
38
|
+
// Section-specific parameters (for addSection operation)
|
|
39
|
+
title: z.string().optional(),
|
|
40
|
+
usageDescription: z.string().optional(),
|
|
41
|
+
contentSample: z.string().optional(),
|
|
42
|
+
contentFormat: z.string().optional(),
|
|
43
|
+
isRequired: z.boolean().optional(),
|
|
44
|
+
ordinal: z.number().int().optional()
|
|
45
|
+
},
|
|
46
|
+
async (params: any) => {
|
|
47
|
+
try {
|
|
48
|
+
const operation = params.operation;
|
|
49
|
+
|
|
50
|
+
// Validate ID for operations that require it
|
|
51
|
+
const requiresId = ['update', 'delete', 'enable', 'disable', 'addSection'];
|
|
52
|
+
if (requiresId.includes(operation) && !params.id) {
|
|
53
|
+
return {
|
|
54
|
+
content: [{
|
|
55
|
+
type: 'text' as const,
|
|
56
|
+
text: JSON.stringify(
|
|
57
|
+
createErrorResponse(`Template ID is required for ${operation} operation`),
|
|
58
|
+
null,
|
|
59
|
+
2
|
|
60
|
+
)
|
|
61
|
+
}]
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
switch (operation) {
|
|
66
|
+
case 'create': {
|
|
67
|
+
// Validate required parameters for create
|
|
68
|
+
if (!params.name || !params.description || !params.targetEntityType) {
|
|
69
|
+
return {
|
|
70
|
+
content: [{
|
|
71
|
+
type: 'text' as const,
|
|
72
|
+
text: JSON.stringify(
|
|
73
|
+
createErrorResponse('name, description, and targetEntityType are required for create operation'),
|
|
74
|
+
null,
|
|
75
|
+
2
|
|
76
|
+
)
|
|
77
|
+
}]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const result = createTemplate({
|
|
82
|
+
name: params.name,
|
|
83
|
+
description: params.description,
|
|
84
|
+
targetEntityType: params.targetEntityType,
|
|
85
|
+
isBuiltIn: params.isBuiltIn,
|
|
86
|
+
isProtected: params.isProtected,
|
|
87
|
+
createdBy: params.createdBy,
|
|
88
|
+
tags: params.tags
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (!result.success) {
|
|
92
|
+
return {
|
|
93
|
+
content: [{
|
|
94
|
+
type: 'text' as const,
|
|
95
|
+
text: JSON.stringify(
|
|
96
|
+
createErrorResponse(result.error || 'Failed to create template'),
|
|
97
|
+
null,
|
|
98
|
+
2
|
|
99
|
+
)
|
|
100
|
+
}]
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
content: [{
|
|
106
|
+
type: 'text' as const,
|
|
107
|
+
text: JSON.stringify(
|
|
108
|
+
createSuccessResponse('Template created successfully', result.data),
|
|
109
|
+
null,
|
|
110
|
+
2
|
|
111
|
+
)
|
|
112
|
+
}]
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
case 'update': {
|
|
117
|
+
const updateParams: any = {};
|
|
118
|
+
if (params.name !== undefined) updateParams.name = params.name;
|
|
119
|
+
if (params.description !== undefined) updateParams.description = params.description;
|
|
120
|
+
if (params.tags !== undefined) updateParams.tags = params.tags;
|
|
121
|
+
|
|
122
|
+
const result = updateTemplate(params.id!, updateParams);
|
|
123
|
+
|
|
124
|
+
if (!result.success) {
|
|
125
|
+
return {
|
|
126
|
+
content: [{
|
|
127
|
+
type: 'text' as const,
|
|
128
|
+
text: JSON.stringify(
|
|
129
|
+
createErrorResponse(result.error || 'Failed to update template'),
|
|
130
|
+
null,
|
|
131
|
+
2
|
|
132
|
+
)
|
|
133
|
+
}]
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
content: [{
|
|
139
|
+
type: 'text' as const,
|
|
140
|
+
text: JSON.stringify(
|
|
141
|
+
createSuccessResponse('Template updated successfully', result.data),
|
|
142
|
+
null,
|
|
143
|
+
2
|
|
144
|
+
)
|
|
145
|
+
}]
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
case 'delete': {
|
|
150
|
+
const result = deleteTemplate(params.id!);
|
|
151
|
+
|
|
152
|
+
if (!result.success) {
|
|
153
|
+
return {
|
|
154
|
+
content: [{
|
|
155
|
+
type: 'text' as const,
|
|
156
|
+
text: JSON.stringify(
|
|
157
|
+
createErrorResponse(result.error || 'Failed to delete template'),
|
|
158
|
+
null,
|
|
159
|
+
2
|
|
160
|
+
)
|
|
161
|
+
}]
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
content: [{
|
|
167
|
+
type: 'text' as const,
|
|
168
|
+
text: JSON.stringify(
|
|
169
|
+
createSuccessResponse('Template deleted successfully', { deleted: true }),
|
|
170
|
+
null,
|
|
171
|
+
2
|
|
172
|
+
)
|
|
173
|
+
}]
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
case 'enable': {
|
|
178
|
+
const result = enableTemplate(params.id!);
|
|
179
|
+
|
|
180
|
+
if (!result.success) {
|
|
181
|
+
return {
|
|
182
|
+
content: [{
|
|
183
|
+
type: 'text' as const,
|
|
184
|
+
text: JSON.stringify(
|
|
185
|
+
createErrorResponse(result.error || 'Failed to enable template'),
|
|
186
|
+
null,
|
|
187
|
+
2
|
|
188
|
+
)
|
|
189
|
+
}]
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
content: [{
|
|
195
|
+
type: 'text' as const,
|
|
196
|
+
text: JSON.stringify(
|
|
197
|
+
createSuccessResponse('Template enabled successfully', result.data),
|
|
198
|
+
null,
|
|
199
|
+
2
|
|
200
|
+
)
|
|
201
|
+
}]
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
case 'disable': {
|
|
206
|
+
const result = disableTemplate(params.id!);
|
|
207
|
+
|
|
208
|
+
if (!result.success) {
|
|
209
|
+
return {
|
|
210
|
+
content: [{
|
|
211
|
+
type: 'text' as const,
|
|
212
|
+
text: JSON.stringify(
|
|
213
|
+
createErrorResponse(result.error || 'Failed to disable template'),
|
|
214
|
+
null,
|
|
215
|
+
2
|
|
216
|
+
)
|
|
217
|
+
}]
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
content: [{
|
|
223
|
+
type: 'text' as const,
|
|
224
|
+
text: JSON.stringify(
|
|
225
|
+
createSuccessResponse('Template disabled successfully', result.data),
|
|
226
|
+
null,
|
|
227
|
+
2
|
|
228
|
+
)
|
|
229
|
+
}]
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
case 'addSection': {
|
|
234
|
+
// Validate required parameters for addSection
|
|
235
|
+
if (!params.title || !params.usageDescription || !params.contentSample) {
|
|
236
|
+
return {
|
|
237
|
+
content: [{
|
|
238
|
+
type: 'text' as const,
|
|
239
|
+
text: JSON.stringify(
|
|
240
|
+
createErrorResponse('title, usageDescription, and contentSample are required for addSection operation'),
|
|
241
|
+
null,
|
|
242
|
+
2
|
|
243
|
+
)
|
|
244
|
+
}]
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const result = addTemplateSection({
|
|
249
|
+
templateId: params.id!,
|
|
250
|
+
title: params.title,
|
|
251
|
+
usageDescription: params.usageDescription,
|
|
252
|
+
contentSample: params.contentSample,
|
|
253
|
+
contentFormat: params.contentFormat,
|
|
254
|
+
isRequired: params.isRequired,
|
|
255
|
+
tags: params.tags,
|
|
256
|
+
ordinal: params.ordinal
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
if (!result.success) {
|
|
260
|
+
return {
|
|
261
|
+
content: [{
|
|
262
|
+
type: 'text' as const,
|
|
263
|
+
text: JSON.stringify(
|
|
264
|
+
createErrorResponse(result.error || 'Failed to add template section'),
|
|
265
|
+
null,
|
|
266
|
+
2
|
|
267
|
+
)
|
|
268
|
+
}]
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return {
|
|
273
|
+
content: [{
|
|
274
|
+
type: 'text' as const,
|
|
275
|
+
text: JSON.stringify(
|
|
276
|
+
createSuccessResponse('Template section added successfully', result.data),
|
|
277
|
+
null,
|
|
278
|
+
2
|
|
279
|
+
)
|
|
280
|
+
}]
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
default:
|
|
285
|
+
return {
|
|
286
|
+
content: [{
|
|
287
|
+
type: 'text' as const,
|
|
288
|
+
text: JSON.stringify(
|
|
289
|
+
createErrorResponse(`Invalid operation: ${operation}`),
|
|
290
|
+
null,
|
|
291
|
+
2
|
|
292
|
+
)
|
|
293
|
+
}]
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
} catch (error: any) {
|
|
297
|
+
return {
|
|
298
|
+
content: [{
|
|
299
|
+
type: 'text' as const,
|
|
300
|
+
text: JSON.stringify(
|
|
301
|
+
createErrorResponse(
|
|
302
|
+
'Internal error',
|
|
303
|
+
error.message || 'Unknown error occurred'
|
|
304
|
+
),
|
|
305
|
+
null,
|
|
306
|
+
2
|
|
307
|
+
)
|
|
308
|
+
}]
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
}
|