@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,333 @@
|
|
|
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
|
+
createProject,
|
|
6
|
+
getProject,
|
|
7
|
+
updateProject,
|
|
8
|
+
deleteProject,
|
|
9
|
+
} from '../repos/projects';
|
|
10
|
+
import {
|
|
11
|
+
createFeature,
|
|
12
|
+
getFeature,
|
|
13
|
+
updateFeature,
|
|
14
|
+
deleteFeature,
|
|
15
|
+
} from '../repos/features';
|
|
16
|
+
import {
|
|
17
|
+
createTask,
|
|
18
|
+
getTask,
|
|
19
|
+
updateTask,
|
|
20
|
+
deleteTask,
|
|
21
|
+
setTaskStatus,
|
|
22
|
+
} from '../repos/tasks';
|
|
23
|
+
import { ProjectStatus, FeatureStatus, TaskStatus, Priority } from '../domain/types';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Unified manage_container tool - write operations for containers
|
|
27
|
+
*
|
|
28
|
+
* Operations:
|
|
29
|
+
* - create: Create a new container
|
|
30
|
+
* - update: Update an existing container (requires version)
|
|
31
|
+
* - delete: Delete a container
|
|
32
|
+
* - setStatus: Update status only (requires version)
|
|
33
|
+
*/
|
|
34
|
+
export function registerManageContainerTool(server: McpServer): void {
|
|
35
|
+
server.tool(
|
|
36
|
+
'manage_container',
|
|
37
|
+
'Unified write operations for containers (project, feature, task). Supports create, update, delete, and setStatus operations.',
|
|
38
|
+
{
|
|
39
|
+
operation: z.enum(['create', 'update', 'delete', 'setStatus']),
|
|
40
|
+
containerType: z.enum(['project', 'feature', 'task']),
|
|
41
|
+
id: optionalUuidSchema,
|
|
42
|
+
// Naming convention: projects/features use `name`, tasks use `title`.
|
|
43
|
+
// Both are the primary display label for their respective container types.
|
|
44
|
+
name: z.string().optional().describe('Display name for project and feature containers. Not used for tasks — use \'title\' instead.'),
|
|
45
|
+
title: z.string().optional().describe('Display title for task containers. Not used for projects/features — use \'name\' instead.'),
|
|
46
|
+
summary: z.string().optional(),
|
|
47
|
+
description: z.string().optional(),
|
|
48
|
+
status: z.string().optional(),
|
|
49
|
+
priority: z.string().optional(),
|
|
50
|
+
projectId: optionalUuidSchema,
|
|
51
|
+
featureId: optionalUuidSchema,
|
|
52
|
+
complexity: z.number().int().optional(),
|
|
53
|
+
tags: z.string().optional(),
|
|
54
|
+
version: z.number().int().optional(),
|
|
55
|
+
},
|
|
56
|
+
async (params) => {
|
|
57
|
+
try {
|
|
58
|
+
const { operation, containerType, id } = params;
|
|
59
|
+
|
|
60
|
+
// ===== CREATE OPERATION =====
|
|
61
|
+
if (operation === 'create') {
|
|
62
|
+
// Projects and features use 'name', tasks use 'title'
|
|
63
|
+
const nameOrTitle =
|
|
64
|
+
containerType === 'task'
|
|
65
|
+
? params.title
|
|
66
|
+
: params.name;
|
|
67
|
+
|
|
68
|
+
if (!nameOrTitle) {
|
|
69
|
+
const fieldName = containerType === 'task' ? 'title' : 'name';
|
|
70
|
+
const response = createErrorResponse(`${fieldName} is required for create operation`);
|
|
71
|
+
return {
|
|
72
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!params.summary) {
|
|
77
|
+
const response = createErrorResponse('summary is required for create operation');
|
|
78
|
+
return {
|
|
79
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Parse tags if provided
|
|
84
|
+
const tags = params.tags ? params.tags.split(',').map((t) => t.trim()) : undefined;
|
|
85
|
+
|
|
86
|
+
let result;
|
|
87
|
+
if (containerType === 'project') {
|
|
88
|
+
result = createProject({
|
|
89
|
+
name: nameOrTitle,
|
|
90
|
+
summary: params.summary,
|
|
91
|
+
description: params.description,
|
|
92
|
+
status: params.status as ProjectStatus | undefined,
|
|
93
|
+
tags,
|
|
94
|
+
});
|
|
95
|
+
} else if (containerType === 'feature') {
|
|
96
|
+
if (!params.priority) {
|
|
97
|
+
const response = createErrorResponse('priority is required for creating a feature');
|
|
98
|
+
return {
|
|
99
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
result = createFeature({
|
|
104
|
+
projectId: params.projectId,
|
|
105
|
+
name: nameOrTitle,
|
|
106
|
+
summary: params.summary,
|
|
107
|
+
description: params.description,
|
|
108
|
+
status: params.status as FeatureStatus | undefined,
|
|
109
|
+
priority: params.priority as Priority,
|
|
110
|
+
tags,
|
|
111
|
+
});
|
|
112
|
+
} else {
|
|
113
|
+
// task
|
|
114
|
+
if (!params.priority) {
|
|
115
|
+
const response = createErrorResponse('priority is required for creating a task');
|
|
116
|
+
return {
|
|
117
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (params.complexity === undefined) {
|
|
122
|
+
const response = createErrorResponse('complexity is required for creating a task');
|
|
123
|
+
return {
|
|
124
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
result = createTask({
|
|
129
|
+
projectId: params.projectId,
|
|
130
|
+
featureId: params.featureId,
|
|
131
|
+
title: nameOrTitle,
|
|
132
|
+
summary: params.summary,
|
|
133
|
+
description: params.description,
|
|
134
|
+
status: params.status as TaskStatus | undefined,
|
|
135
|
+
priority: params.priority as Priority,
|
|
136
|
+
complexity: params.complexity,
|
|
137
|
+
tags,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!result.success) {
|
|
142
|
+
const response = createErrorResponse(result.error || 'Failed to create container');
|
|
143
|
+
return {
|
|
144
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const response = createSuccessResponse(
|
|
149
|
+
`${containerType} created successfully`,
|
|
150
|
+
{ [containerType]: result.data }
|
|
151
|
+
);
|
|
152
|
+
return {
|
|
153
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ===== UPDATE OPERATION =====
|
|
158
|
+
if (operation === 'update') {
|
|
159
|
+
if (!id) {
|
|
160
|
+
const response = createErrorResponse('id is required for update operation');
|
|
161
|
+
return {
|
|
162
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (params.version === undefined) {
|
|
167
|
+
const response = createErrorResponse('version is required for update operation');
|
|
168
|
+
return {
|
|
169
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Parse tags if provided
|
|
174
|
+
const tags = params.tags ? params.tags.split(',').map((t) => t.trim()) : undefined;
|
|
175
|
+
|
|
176
|
+
let result;
|
|
177
|
+
if (containerType === 'project') {
|
|
178
|
+
result = updateProject(id, {
|
|
179
|
+
name: params.name,
|
|
180
|
+
summary: params.summary,
|
|
181
|
+
description: params.description,
|
|
182
|
+
status: params.status as ProjectStatus | undefined,
|
|
183
|
+
tags,
|
|
184
|
+
version: params.version,
|
|
185
|
+
});
|
|
186
|
+
} else if (containerType === 'feature') {
|
|
187
|
+
result = updateFeature(id, {
|
|
188
|
+
name: params.name,
|
|
189
|
+
summary: params.summary,
|
|
190
|
+
description: params.description,
|
|
191
|
+
status: params.status as FeatureStatus | undefined,
|
|
192
|
+
priority: params.priority as Priority | undefined,
|
|
193
|
+
projectId: params.projectId,
|
|
194
|
+
tags,
|
|
195
|
+
version: params.version,
|
|
196
|
+
});
|
|
197
|
+
} else {
|
|
198
|
+
// task
|
|
199
|
+
result = updateTask(id, {
|
|
200
|
+
title: params.title,
|
|
201
|
+
summary: params.summary,
|
|
202
|
+
description: params.description,
|
|
203
|
+
status: params.status as TaskStatus | undefined,
|
|
204
|
+
priority: params.priority as Priority | undefined,
|
|
205
|
+
complexity: params.complexity,
|
|
206
|
+
projectId: params.projectId,
|
|
207
|
+
featureId: params.featureId,
|
|
208
|
+
tags,
|
|
209
|
+
version: params.version,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (!result.success) {
|
|
214
|
+
const response = createErrorResponse(result.error || 'Failed to update container');
|
|
215
|
+
return {
|
|
216
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const response = createSuccessResponse(
|
|
221
|
+
`${containerType} updated successfully`,
|
|
222
|
+
{ [containerType]: result.data }
|
|
223
|
+
);
|
|
224
|
+
return {
|
|
225
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ===== DELETE OPERATION =====
|
|
230
|
+
if (operation === 'delete') {
|
|
231
|
+
if (!id) {
|
|
232
|
+
const response = createErrorResponse('id is required for delete operation');
|
|
233
|
+
return {
|
|
234
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let result;
|
|
239
|
+
if (containerType === 'project') {
|
|
240
|
+
result = deleteProject(id);
|
|
241
|
+
} else if (containerType === 'feature') {
|
|
242
|
+
result = deleteFeature(id);
|
|
243
|
+
} else {
|
|
244
|
+
result = deleteTask(id);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (!result.success) {
|
|
248
|
+
const response = createErrorResponse(result.error || 'Failed to delete container');
|
|
249
|
+
return {
|
|
250
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const response = createSuccessResponse(
|
|
255
|
+
`${containerType} deleted successfully`,
|
|
256
|
+
{ deleted: true }
|
|
257
|
+
);
|
|
258
|
+
return {
|
|
259
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ===== SET STATUS OPERATION =====
|
|
264
|
+
if (operation === 'setStatus') {
|
|
265
|
+
if (!id) {
|
|
266
|
+
const response = createErrorResponse('id is required for setStatus operation');
|
|
267
|
+
return {
|
|
268
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (!params.status) {
|
|
273
|
+
const response = createErrorResponse('status is required for setStatus operation');
|
|
274
|
+
return {
|
|
275
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (params.version === undefined) {
|
|
280
|
+
const response = createErrorResponse('version is required for setStatus operation');
|
|
281
|
+
return {
|
|
282
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
let result;
|
|
287
|
+
if (containerType === 'task') {
|
|
288
|
+
// Tasks have a dedicated setTaskStatus function
|
|
289
|
+
result = setTaskStatus(id, params.status as TaskStatus, params.version);
|
|
290
|
+
} else {
|
|
291
|
+
// For projects and features, use update with only status
|
|
292
|
+
if (containerType === 'project') {
|
|
293
|
+
result = updateProject(id, {
|
|
294
|
+
status: params.status as ProjectStatus,
|
|
295
|
+
version: params.version,
|
|
296
|
+
});
|
|
297
|
+
} else {
|
|
298
|
+
result = updateFeature(id, {
|
|
299
|
+
status: params.status as FeatureStatus,
|
|
300
|
+
version: params.version,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (!result.success) {
|
|
306
|
+
const response = createErrorResponse(result.error || 'Failed to set status');
|
|
307
|
+
return {
|
|
308
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const response = createSuccessResponse(
|
|
313
|
+
`${containerType} status updated successfully`,
|
|
314
|
+
{ [containerType]: result.data }
|
|
315
|
+
);
|
|
316
|
+
return {
|
|
317
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const response = createErrorResponse('Invalid operation');
|
|
322
|
+
return {
|
|
323
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
324
|
+
};
|
|
325
|
+
} catch (error: any) {
|
|
326
|
+
const response = createErrorResponse(error.message || 'Internal error');
|
|
327
|
+
return {
|
|
328
|
+
content: [{ type: 'text' as const, text: JSON.stringify(response, null, 2) }],
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
);
|
|
333
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { createSuccessResponse, createErrorResponse, uuidSchema, optionalUuidSchema } from './registry';
|
|
4
|
+
import { createDependency, deleteDependency } from '../repos/dependencies';
|
|
5
|
+
import { DependencyType } from '../domain/types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Register the manage_dependency MCP tool.
|
|
9
|
+
*
|
|
10
|
+
* Manages dependencies between tasks with create and delete operations.
|
|
11
|
+
*
|
|
12
|
+
* @param server - The MCP server instance to register the tool with
|
|
13
|
+
*/
|
|
14
|
+
export function registerManageDependencyTool(server: McpServer): void {
|
|
15
|
+
server.tool(
|
|
16
|
+
'manage_dependency',
|
|
17
|
+
'Manage dependencies between tasks (create, delete)',
|
|
18
|
+
{
|
|
19
|
+
operation: z
|
|
20
|
+
.enum(['create', 'delete'])
|
|
21
|
+
.describe('Operation to perform: create or delete'),
|
|
22
|
+
id: optionalUuidSchema
|
|
23
|
+
.describe('Dependency ID (required for delete operation)'),
|
|
24
|
+
fromTaskId: optionalUuidSchema
|
|
25
|
+
.describe('Source task ID (required for create operation)'),
|
|
26
|
+
toTaskId: optionalUuidSchema
|
|
27
|
+
.describe('Target task ID (required for create operation)'),
|
|
28
|
+
type: z
|
|
29
|
+
.enum(['BLOCKS', 'IS_BLOCKED_BY', 'RELATES_TO'])
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Dependency type (required for create operation)'),
|
|
32
|
+
},
|
|
33
|
+
async (params) => {
|
|
34
|
+
try {
|
|
35
|
+
const { operation } = params;
|
|
36
|
+
|
|
37
|
+
// Handle create operation
|
|
38
|
+
if (operation === 'create') {
|
|
39
|
+
const { fromTaskId, toTaskId, type } = params;
|
|
40
|
+
|
|
41
|
+
// Validate required parameters for create
|
|
42
|
+
if (!fromTaskId) {
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text' as const,
|
|
47
|
+
text: JSON.stringify(
|
|
48
|
+
createErrorResponse('fromTaskId is required for create operation'),
|
|
49
|
+
null,
|
|
50
|
+
2
|
|
51
|
+
),
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!toTaskId) {
|
|
58
|
+
return {
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
61
|
+
type: 'text' as const,
|
|
62
|
+
text: JSON.stringify(
|
|
63
|
+
createErrorResponse('toTaskId is required for create operation'),
|
|
64
|
+
null,
|
|
65
|
+
2
|
|
66
|
+
),
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!type) {
|
|
73
|
+
return {
|
|
74
|
+
content: [
|
|
75
|
+
{
|
|
76
|
+
type: 'text' as const,
|
|
77
|
+
text: JSON.stringify(
|
|
78
|
+
createErrorResponse('type is required for create operation'),
|
|
79
|
+
null,
|
|
80
|
+
2
|
|
81
|
+
),
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const result = createDependency({
|
|
88
|
+
fromTaskId,
|
|
89
|
+
toTaskId,
|
|
90
|
+
type: type as DependencyType,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (result.success === false) {
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: 'text' as const,
|
|
98
|
+
text: JSON.stringify(
|
|
99
|
+
createErrorResponse(result.error, result.code),
|
|
100
|
+
null,
|
|
101
|
+
2
|
|
102
|
+
),
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
content: [
|
|
110
|
+
{
|
|
111
|
+
type: 'text' as const,
|
|
112
|
+
text: JSON.stringify(
|
|
113
|
+
createSuccessResponse('Dependency created', result.data),
|
|
114
|
+
null,
|
|
115
|
+
2
|
|
116
|
+
),
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Handle delete operation
|
|
123
|
+
if (operation === 'delete') {
|
|
124
|
+
const { id } = params;
|
|
125
|
+
|
|
126
|
+
// Validate required parameters for delete
|
|
127
|
+
if (!id) {
|
|
128
|
+
return {
|
|
129
|
+
content: [
|
|
130
|
+
{
|
|
131
|
+
type: 'text' as const,
|
|
132
|
+
text: JSON.stringify(
|
|
133
|
+
createErrorResponse('id is required for delete operation'),
|
|
134
|
+
null,
|
|
135
|
+
2
|
|
136
|
+
),
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const result = deleteDependency(id);
|
|
143
|
+
|
|
144
|
+
if (result.success === false) {
|
|
145
|
+
return {
|
|
146
|
+
content: [
|
|
147
|
+
{
|
|
148
|
+
type: 'text' as const,
|
|
149
|
+
text: JSON.stringify(
|
|
150
|
+
createErrorResponse(result.error, result.code),
|
|
151
|
+
null,
|
|
152
|
+
2
|
|
153
|
+
),
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
content: [
|
|
161
|
+
{
|
|
162
|
+
type: 'text' as const,
|
|
163
|
+
text: JSON.stringify(
|
|
164
|
+
createSuccessResponse('Dependency deleted', { deleted: true }),
|
|
165
|
+
null,
|
|
166
|
+
2
|
|
167
|
+
),
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Invalid operation (should never happen due to enum validation)
|
|
174
|
+
return {
|
|
175
|
+
content: [
|
|
176
|
+
{
|
|
177
|
+
type: 'text' as const,
|
|
178
|
+
text: JSON.stringify(
|
|
179
|
+
createErrorResponse(`Invalid operation: ${operation}`),
|
|
180
|
+
null,
|
|
181
|
+
2
|
|
182
|
+
),
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
};
|
|
186
|
+
} catch (error: any) {
|
|
187
|
+
return {
|
|
188
|
+
content: [
|
|
189
|
+
{
|
|
190
|
+
type: 'text' as const,
|
|
191
|
+
text: JSON.stringify(createErrorResponse(error.message), null, 2),
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
}
|