@vibescope/mcp-server 0.1.0 → 0.2.1
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 +1 -1
- package/dist/api-client.d.ts +120 -2
- package/dist/api-client.js +51 -5
- package/dist/handlers/bodies-of-work.js +84 -50
- package/dist/handlers/cost.js +62 -54
- package/dist/handlers/decisions.js +29 -16
- package/dist/handlers/deployment.js +114 -107
- package/dist/handlers/discovery.d.ts +3 -0
- package/dist/handlers/discovery.js +55 -657
- package/dist/handlers/fallback.js +42 -28
- package/dist/handlers/file-checkouts.d.ts +18 -0
- package/dist/handlers/file-checkouts.js +101 -0
- package/dist/handlers/findings.d.ts +14 -1
- package/dist/handlers/findings.js +104 -28
- package/dist/handlers/git-issues.js +36 -32
- package/dist/handlers/ideas.js +44 -26
- package/dist/handlers/index.d.ts +2 -0
- package/dist/handlers/index.js +6 -0
- package/dist/handlers/milestones.js +34 -27
- package/dist/handlers/organizations.js +86 -78
- package/dist/handlers/progress.js +22 -11
- package/dist/handlers/project.js +62 -22
- package/dist/handlers/requests.js +15 -11
- package/dist/handlers/roles.d.ts +18 -0
- package/dist/handlers/roles.js +130 -0
- package/dist/handlers/session.js +52 -15
- package/dist/handlers/sprints.js +78 -65
- package/dist/handlers/tasks.js +135 -74
- package/dist/handlers/tool-docs.d.ts +4 -3
- package/dist/handlers/tool-docs.js +252 -5
- package/dist/handlers/validation.js +30 -14
- package/dist/index.js +25 -7
- package/dist/tools.js +417 -4
- package/package.json +1 -1
- package/src/api-client.ts +161 -8
- package/src/handlers/__test-setup__.ts +12 -0
- package/src/handlers/bodies-of-work.ts +127 -111
- package/src/handlers/cost.test.ts +34 -44
- package/src/handlers/cost.ts +77 -92
- package/src/handlers/decisions.test.ts +3 -2
- package/src/handlers/decisions.ts +32 -27
- package/src/handlers/deployment.ts +144 -190
- package/src/handlers/discovery.test.ts +4 -5
- package/src/handlers/discovery.ts +60 -746
- package/src/handlers/fallback.test.ts +78 -0
- package/src/handlers/fallback.ts +51 -38
- package/src/handlers/file-checkouts.test.ts +477 -0
- package/src/handlers/file-checkouts.ts +127 -0
- package/src/handlers/findings.test.ts +274 -2
- package/src/handlers/findings.ts +123 -57
- package/src/handlers/git-issues.ts +40 -80
- package/src/handlers/ideas.ts +56 -54
- package/src/handlers/index.ts +6 -0
- package/src/handlers/milestones.test.ts +1 -1
- package/src/handlers/milestones.ts +47 -45
- package/src/handlers/organizations.ts +104 -129
- package/src/handlers/progress.ts +24 -22
- package/src/handlers/project.ts +89 -57
- package/src/handlers/requests.ts +18 -14
- package/src/handlers/roles.test.ts +303 -0
- package/src/handlers/roles.ts +208 -0
- package/src/handlers/session.test.ts +37 -2
- package/src/handlers/session.ts +64 -21
- package/src/handlers/sprints.ts +114 -134
- package/src/handlers/tasks.test.ts +61 -0
- package/src/handlers/tasks.ts +170 -139
- package/src/handlers/tool-docs.ts +1024 -0
- package/src/handlers/validation.test.ts +53 -1
- package/src/handlers/validation.ts +32 -21
- package/src/index.ts +25 -7
- package/src/tools.ts +417 -4
- package/dist/config/tool-categories.d.ts +0 -31
- package/dist/config/tool-categories.js +0 -253
- package/dist/knowledge.d.ts +0 -6
- package/dist/knowledge.js +0 -218
- package/src/knowledge.ts +0 -230
package/dist/handlers/tasks.js
CHANGED
|
@@ -15,8 +15,82 @@
|
|
|
15
15
|
* - add_subtask
|
|
16
16
|
* - get_subtasks
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import { parseArgs, uuidValidator, taskStatusValidator, priorityValidator, progressValidator, minutesValidator, createEnumValidator, ValidationError, } from '../validators.js';
|
|
19
19
|
import { getApiClient } from '../api-client.js';
|
|
20
|
+
// Valid task types
|
|
21
|
+
const VALID_TASK_TYPES = [
|
|
22
|
+
'frontend', 'backend', 'database', 'feature', 'bugfix',
|
|
23
|
+
'design', 'mcp', 'testing', 'docs', 'infra', 'other'
|
|
24
|
+
];
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Argument Schemas
|
|
27
|
+
// ============================================================================
|
|
28
|
+
const getTasksSchema = {
|
|
29
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
30
|
+
status: { type: 'string', validate: taskStatusValidator },
|
|
31
|
+
limit: { type: 'number', default: 50 },
|
|
32
|
+
offset: { type: 'number', default: 0 },
|
|
33
|
+
search_query: { type: 'string' },
|
|
34
|
+
include_subtasks: { type: 'boolean', default: false },
|
|
35
|
+
include_metadata: { type: 'boolean', default: false },
|
|
36
|
+
};
|
|
37
|
+
const getNextTaskSchema = {
|
|
38
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
39
|
+
};
|
|
40
|
+
const addTaskSchema = {
|
|
41
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
42
|
+
title: { type: 'string', required: true },
|
|
43
|
+
description: { type: 'string' },
|
|
44
|
+
priority: { type: 'number', default: 3, validate: priorityValidator },
|
|
45
|
+
estimated_minutes: { type: 'number', validate: minutesValidator },
|
|
46
|
+
blocking: { type: 'boolean', default: false },
|
|
47
|
+
task_type: { type: 'string', validate: createEnumValidator(VALID_TASK_TYPES) },
|
|
48
|
+
};
|
|
49
|
+
const updateTaskSchema = {
|
|
50
|
+
task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
51
|
+
title: { type: 'string' },
|
|
52
|
+
description: { type: 'string' },
|
|
53
|
+
priority: { type: 'number', validate: priorityValidator },
|
|
54
|
+
status: { type: 'string', validate: taskStatusValidator },
|
|
55
|
+
progress_percentage: { type: 'number', validate: progressValidator },
|
|
56
|
+
progress_note: { type: 'string' },
|
|
57
|
+
estimated_minutes: { type: 'number', validate: minutesValidator },
|
|
58
|
+
git_branch: { type: 'string' },
|
|
59
|
+
task_type: { type: 'string', validate: createEnumValidator(VALID_TASK_TYPES) },
|
|
60
|
+
};
|
|
61
|
+
const completeTaskSchema = {
|
|
62
|
+
task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
63
|
+
summary: { type: 'string' },
|
|
64
|
+
};
|
|
65
|
+
const deleteTaskSchema = {
|
|
66
|
+
task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
67
|
+
};
|
|
68
|
+
const addTaskReferenceSchema = {
|
|
69
|
+
task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
70
|
+
url: { type: 'string', required: true },
|
|
71
|
+
label: { type: 'string' },
|
|
72
|
+
};
|
|
73
|
+
const removeTaskReferenceSchema = {
|
|
74
|
+
task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
75
|
+
url: { type: 'string', required: true },
|
|
76
|
+
};
|
|
77
|
+
const batchUpdateTasksSchema = {
|
|
78
|
+
updates: { type: 'array', required: true },
|
|
79
|
+
};
|
|
80
|
+
const batchCompleteTasksSchema = {
|
|
81
|
+
completions: { type: 'array', required: true },
|
|
82
|
+
};
|
|
83
|
+
const addSubtaskSchema = {
|
|
84
|
+
parent_task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
85
|
+
title: { type: 'string', required: true },
|
|
86
|
+
description: { type: 'string' },
|
|
87
|
+
priority: { type: 'number', validate: priorityValidator },
|
|
88
|
+
estimated_minutes: { type: 'number', validate: minutesValidator },
|
|
89
|
+
};
|
|
90
|
+
const getSubtasksSchema = {
|
|
91
|
+
parent_task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
92
|
+
status: { type: 'string', validate: taskStatusValidator },
|
|
93
|
+
};
|
|
20
94
|
function getTaskCompleteGitInstructions(gitWorkflow, gitMainBranch, gitDevelopBranch, taskBranch, taskTitle, taskId) {
|
|
21
95
|
if (gitWorkflow === 'none') {
|
|
22
96
|
return undefined;
|
|
@@ -68,14 +142,11 @@ export function getValidationApprovedGitInstructions(config, taskBranch) {
|
|
|
68
142
|
// Task Handlers - Using API Client
|
|
69
143
|
// ============================================================================
|
|
70
144
|
export const getTasks = async (args, ctx) => {
|
|
71
|
-
const { project_id, status, limit
|
|
72
|
-
validateRequired(project_id, 'project_id');
|
|
73
|
-
validateUUID(project_id, 'project_id');
|
|
74
|
-
validateTaskStatus(status);
|
|
145
|
+
const { project_id, status, limit, offset, search_query, include_subtasks, include_metadata } = parseArgs(args, getTasksSchema);
|
|
75
146
|
const api = getApiClient();
|
|
76
147
|
const response = await api.getTasks(project_id, {
|
|
77
148
|
status,
|
|
78
|
-
limit: Math.min(limit, 200),
|
|
149
|
+
limit: Math.min(limit ?? 50, 200),
|
|
79
150
|
offset,
|
|
80
151
|
include_subtasks,
|
|
81
152
|
search_query,
|
|
@@ -93,9 +164,7 @@ export const getTasks = async (args, ctx) => {
|
|
|
93
164
|
};
|
|
94
165
|
};
|
|
95
166
|
export const getNextTask = async (args, ctx) => {
|
|
96
|
-
const { project_id } = args;
|
|
97
|
-
validateRequired(project_id, 'project_id');
|
|
98
|
-
validateUUID(project_id, 'project_id');
|
|
167
|
+
const { project_id } = parseArgs(args, getNextTaskSchema);
|
|
99
168
|
const api = getApiClient();
|
|
100
169
|
const response = await api.getNextTask(project_id, ctx.session.currentSessionId || undefined);
|
|
101
170
|
if (!response.ok) {
|
|
@@ -138,12 +207,7 @@ export const getNextTask = async (args, ctx) => {
|
|
|
138
207
|
return { result };
|
|
139
208
|
};
|
|
140
209
|
export const addTask = async (args, ctx) => {
|
|
141
|
-
const { project_id, title, description, priority
|
|
142
|
-
validateRequired(project_id, 'project_id');
|
|
143
|
-
validateRequired(title, 'title');
|
|
144
|
-
validateUUID(project_id, 'project_id');
|
|
145
|
-
validatePriority(priority);
|
|
146
|
-
validateEstimatedMinutes(estimated_minutes);
|
|
210
|
+
const { project_id, title, description, priority, estimated_minutes, blocking, task_type } = parseArgs(args, addTaskSchema);
|
|
147
211
|
const api = getApiClient();
|
|
148
212
|
const response = await api.createTask(project_id, {
|
|
149
213
|
title,
|
|
@@ -152,6 +216,7 @@ export const addTask = async (args, ctx) => {
|
|
|
152
216
|
estimated_minutes,
|
|
153
217
|
blocking,
|
|
154
218
|
session_id: ctx.session.currentSessionId || undefined,
|
|
219
|
+
task_type,
|
|
155
220
|
});
|
|
156
221
|
if (!response.ok) {
|
|
157
222
|
throw new Error(`Failed to add task: ${response.error}`);
|
|
@@ -169,13 +234,8 @@ export const addTask = async (args, ctx) => {
|
|
|
169
234
|
return { result };
|
|
170
235
|
};
|
|
171
236
|
export const updateTask = async (args, ctx) => {
|
|
172
|
-
const { task_id, progress_note,
|
|
173
|
-
|
|
174
|
-
validateUUID(task_id, 'task_id');
|
|
175
|
-
validateTaskStatus(updates.status);
|
|
176
|
-
validatePriority(updates.priority);
|
|
177
|
-
validateProgressPercentage(updates.progress_percentage);
|
|
178
|
-
validateEstimatedMinutes(updates.estimated_minutes);
|
|
237
|
+
const { task_id, title, description, priority, status, progress_percentage, progress_note, estimated_minutes, git_branch, task_type } = parseArgs(args, updateTaskSchema);
|
|
238
|
+
const updates = { title, description, priority, status, progress_percentage, estimated_minutes, git_branch, task_type };
|
|
179
239
|
const api = getApiClient();
|
|
180
240
|
const response = await api.updateTask(task_id, {
|
|
181
241
|
...updates,
|
|
@@ -208,14 +268,39 @@ export const updateTask = async (args, ctx) => {
|
|
|
208
268
|
},
|
|
209
269
|
};
|
|
210
270
|
}
|
|
271
|
+
if (response.error?.includes('branch_conflict')) {
|
|
272
|
+
return {
|
|
273
|
+
result: {
|
|
274
|
+
error: 'branch_conflict',
|
|
275
|
+
message: response.error,
|
|
276
|
+
conflicting_task_id: response.data?.conflicting_task_id,
|
|
277
|
+
conflicting_task_title: response.data?.conflicting_task_title,
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
}
|
|
211
281
|
throw new Error(`Failed to update task: ${response.error}`);
|
|
212
282
|
}
|
|
213
|
-
|
|
283
|
+
// Build result - include git workflow info when transitioning to in_progress
|
|
284
|
+
const data = response.data;
|
|
285
|
+
const result = { success: true, task_id };
|
|
286
|
+
if (data?.git_workflow) {
|
|
287
|
+
result.git_workflow = data.git_workflow;
|
|
288
|
+
}
|
|
289
|
+
if (data?.worktree_setup) {
|
|
290
|
+
result.worktree_setup = data.worktree_setup;
|
|
291
|
+
}
|
|
292
|
+
if (data?.next_step) {
|
|
293
|
+
result.next_step = data.next_step;
|
|
294
|
+
}
|
|
295
|
+
// Warn if transitioning to in_progress without git_branch
|
|
296
|
+
if (updates.status === 'in_progress' && !updates.git_branch) {
|
|
297
|
+
result.warning = 'git_branch not set. For multi-agent collaboration, set git_branch when marking in_progress to track your worktree.';
|
|
298
|
+
result.hint = 'Call update_task again with git_branch parameter after creating your worktree.';
|
|
299
|
+
}
|
|
300
|
+
return { result };
|
|
214
301
|
};
|
|
215
302
|
export const completeTask = async (args, ctx) => {
|
|
216
|
-
const { task_id, summary } = args;
|
|
217
|
-
validateRequired(task_id, 'task_id');
|
|
218
|
-
validateUUID(task_id, 'task_id');
|
|
303
|
+
const { task_id, summary } = parseArgs(args, completeTaskSchema);
|
|
219
304
|
const api = getApiClient();
|
|
220
305
|
const response = await api.completeTask(task_id, {
|
|
221
306
|
summary,
|
|
@@ -239,15 +324,17 @@ export const completeTask = async (args, ctx) => {
|
|
|
239
324
|
if (data.context) {
|
|
240
325
|
result.context = data.context;
|
|
241
326
|
}
|
|
327
|
+
// Pass through warnings (e.g., missing git_branch)
|
|
328
|
+
if (data.warnings) {
|
|
329
|
+
result.warnings = data.warnings;
|
|
330
|
+
}
|
|
242
331
|
// Git workflow instructions are already in API response but we need to fetch
|
|
243
332
|
// task details if we want to include them (API should return these)
|
|
244
333
|
result.next_action = data.next_action;
|
|
245
334
|
return { result };
|
|
246
335
|
};
|
|
247
336
|
export const deleteTask = async (args, ctx) => {
|
|
248
|
-
const { task_id } = args;
|
|
249
|
-
validateRequired(task_id, 'task_id');
|
|
250
|
-
validateUUID(task_id, 'task_id');
|
|
337
|
+
const { task_id } = parseArgs(args, deleteTaskSchema);
|
|
251
338
|
const api = getApiClient();
|
|
252
339
|
const response = await api.deleteTask(task_id);
|
|
253
340
|
if (!response.ok) {
|
|
@@ -256,10 +343,7 @@ export const deleteTask = async (args, ctx) => {
|
|
|
256
343
|
return { result: { success: true, deleted_id: task_id } };
|
|
257
344
|
};
|
|
258
345
|
export const addTaskReference = async (args, ctx) => {
|
|
259
|
-
const { task_id, url, label } = args;
|
|
260
|
-
validateRequired(task_id, 'task_id');
|
|
261
|
-
validateUUID(task_id, 'task_id');
|
|
262
|
-
validateRequired(url, 'url');
|
|
346
|
+
const { task_id, url, label } = parseArgs(args, addTaskReferenceSchema);
|
|
263
347
|
const api = getApiClient();
|
|
264
348
|
const response = await api.addTaskReference(task_id, url, label);
|
|
265
349
|
if (!response.ok) {
|
|
@@ -276,10 +360,7 @@ export const addTaskReference = async (args, ctx) => {
|
|
|
276
360
|
};
|
|
277
361
|
};
|
|
278
362
|
export const removeTaskReference = async (args, ctx) => {
|
|
279
|
-
const { task_id, url } = args;
|
|
280
|
-
validateRequired(task_id, 'task_id');
|
|
281
|
-
validateUUID(task_id, 'task_id');
|
|
282
|
-
validateRequired(url, 'url');
|
|
363
|
+
const { task_id, url } = parseArgs(args, removeTaskReferenceSchema);
|
|
283
364
|
const api = getApiClient();
|
|
284
365
|
const response = await api.removeTaskReference(task_id, url);
|
|
285
366
|
if (!response.ok) {
|
|
@@ -291,61 +372,52 @@ export const removeTaskReference = async (args, ctx) => {
|
|
|
291
372
|
return { result: { success: true } };
|
|
292
373
|
};
|
|
293
374
|
export const batchUpdateTasks = async (args, ctx) => {
|
|
294
|
-
const { updates } = args;
|
|
295
|
-
|
|
375
|
+
const { updates } = parseArgs(args, batchUpdateTasksSchema);
|
|
376
|
+
const typedUpdates = updates;
|
|
377
|
+
if (!Array.isArray(typedUpdates) || typedUpdates.length === 0) {
|
|
296
378
|
throw new ValidationError('updates must be a non-empty array', {
|
|
297
379
|
field: 'updates',
|
|
298
380
|
hint: 'Provide an array of task updates with at least one item',
|
|
299
381
|
});
|
|
300
382
|
}
|
|
301
|
-
if (
|
|
383
|
+
if (typedUpdates.length > 50) {
|
|
302
384
|
throw new ValidationError('Too many updates. Maximum is 50 per batch.', {
|
|
303
385
|
field: 'updates',
|
|
304
386
|
hint: 'Split your updates into smaller batches',
|
|
305
387
|
});
|
|
306
388
|
}
|
|
307
|
-
//
|
|
308
|
-
for (const update of updates) {
|
|
309
|
-
validateRequired(update.task_id, 'task_id');
|
|
310
|
-
validateUUID(update.task_id, 'task_id');
|
|
311
|
-
validateTaskStatus(update.status);
|
|
312
|
-
validatePriority(update.priority);
|
|
313
|
-
validateProgressPercentage(update.progress_percentage);
|
|
314
|
-
}
|
|
389
|
+
// Individual item validation happens at API level
|
|
315
390
|
const api = getApiClient();
|
|
316
|
-
const response = await api.batchUpdateTasks(
|
|
391
|
+
const response = await api.batchUpdateTasks(typedUpdates);
|
|
317
392
|
if (!response.ok) {
|
|
318
393
|
throw new Error(`Failed to batch update tasks: ${response.error}`);
|
|
319
394
|
}
|
|
320
395
|
return {
|
|
321
396
|
result: {
|
|
322
397
|
success: response.data?.success || false,
|
|
323
|
-
total:
|
|
398
|
+
total: typedUpdates.length,
|
|
324
399
|
succeeded: response.data?.updated_count || 0,
|
|
325
400
|
},
|
|
326
401
|
};
|
|
327
402
|
};
|
|
328
403
|
export const batchCompleteTasks = async (args, ctx) => {
|
|
329
|
-
const { completions } = args;
|
|
330
|
-
|
|
404
|
+
const { completions } = parseArgs(args, batchCompleteTasksSchema);
|
|
405
|
+
const typedCompletions = completions;
|
|
406
|
+
if (!Array.isArray(typedCompletions) || typedCompletions.length === 0) {
|
|
331
407
|
throw new ValidationError('completions must be a non-empty array', {
|
|
332
408
|
field: 'completions',
|
|
333
409
|
hint: 'Provide an array of task completions with at least one item',
|
|
334
410
|
});
|
|
335
411
|
}
|
|
336
|
-
if (
|
|
412
|
+
if (typedCompletions.length > 50) {
|
|
337
413
|
throw new ValidationError('Too many completions. Maximum is 50 per batch.', {
|
|
338
414
|
field: 'completions',
|
|
339
415
|
hint: 'Split your completions into smaller batches',
|
|
340
416
|
});
|
|
341
417
|
}
|
|
342
|
-
//
|
|
343
|
-
for (const completion of completions) {
|
|
344
|
-
validateRequired(completion.task_id, 'task_id');
|
|
345
|
-
validateUUID(completion.task_id, 'task_id');
|
|
346
|
-
}
|
|
418
|
+
// Individual item validation happens at API level
|
|
347
419
|
const api = getApiClient();
|
|
348
|
-
const response = await api.batchCompleteTasks(
|
|
420
|
+
const response = await api.batchCompleteTasks(typedCompletions);
|
|
349
421
|
if (!response.ok) {
|
|
350
422
|
throw new Error(`Failed to batch complete tasks: ${response.error}`);
|
|
351
423
|
}
|
|
@@ -353,9 +425,9 @@ export const batchCompleteTasks = async (args, ctx) => {
|
|
|
353
425
|
return {
|
|
354
426
|
result: {
|
|
355
427
|
success: data?.success || false,
|
|
356
|
-
total:
|
|
428
|
+
total: typedCompletions.length,
|
|
357
429
|
succeeded: data?.completed_count || 0,
|
|
358
|
-
failed:
|
|
430
|
+
failed: typedCompletions.length - (data?.completed_count || 0),
|
|
359
431
|
next_task: data?.next_task,
|
|
360
432
|
},
|
|
361
433
|
};
|
|
@@ -364,14 +436,7 @@ export const batchCompleteTasks = async (args, ctx) => {
|
|
|
364
436
|
// Subtask Handlers
|
|
365
437
|
// ============================================================================
|
|
366
438
|
export const addSubtask = async (args, ctx) => {
|
|
367
|
-
const { parent_task_id, title, description, priority, estimated_minutes } = args;
|
|
368
|
-
validateRequired(parent_task_id, 'parent_task_id');
|
|
369
|
-
validateUUID(parent_task_id, 'parent_task_id');
|
|
370
|
-
validateRequired(title, 'title');
|
|
371
|
-
if (priority !== undefined)
|
|
372
|
-
validatePriority(priority);
|
|
373
|
-
if (estimated_minutes !== undefined)
|
|
374
|
-
validateEstimatedMinutes(estimated_minutes);
|
|
439
|
+
const { parent_task_id, title, description, priority, estimated_minutes } = parseArgs(args, addSubtaskSchema);
|
|
375
440
|
const api = getApiClient();
|
|
376
441
|
const response = await api.addSubtask(parent_task_id, {
|
|
377
442
|
title,
|
|
@@ -400,11 +465,7 @@ export const addSubtask = async (args, ctx) => {
|
|
|
400
465
|
};
|
|
401
466
|
};
|
|
402
467
|
export const getSubtasks = async (args, ctx) => {
|
|
403
|
-
const { parent_task_id, status } = args;
|
|
404
|
-
validateRequired(parent_task_id, 'parent_task_id');
|
|
405
|
-
validateUUID(parent_task_id, 'parent_task_id');
|
|
406
|
-
if (status)
|
|
407
|
-
validateTaskStatus(status);
|
|
468
|
+
const { parent_task_id, status } = parseArgs(args, getSubtasksSchema);
|
|
408
469
|
const api = getApiClient();
|
|
409
470
|
const response = await api.getSubtasks(parent_task_id, status);
|
|
410
471
|
if (!response.ok) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool Documentation
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Externalized documentation for all MCP tools.
|
|
5
|
+
* This file is lazy-loaded by get_tool_info to save tokens.
|
|
6
|
+
*
|
|
7
|
+
* Token savings: ~8,000 tokens per schema load when this isn't bundled.
|
|
7
8
|
*/
|
|
8
9
|
export declare const TOOL_INFO: Record<string, string>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool Documentation
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Externalized documentation for all MCP tools.
|
|
5
|
+
* This file is lazy-loaded by get_tool_info to save tokens.
|
|
6
|
+
*
|
|
7
|
+
* Token savings: ~8,000 tokens per schema load when this isn't bundled.
|
|
7
8
|
*/
|
|
8
9
|
export const TOOL_INFO = {
|
|
9
10
|
start_work_session: `# start_work_session
|
|
@@ -32,7 +33,8 @@ Get token usage statistics for current session.
|
|
|
32
33
|
Send heartbeat to maintain active status. Call every 30-60 seconds.
|
|
33
34
|
|
|
34
35
|
**Parameters:**
|
|
35
|
-
- session_id (optional): Uses current session if not provided
|
|
36
|
+
- session_id (optional): Uses current session if not provided
|
|
37
|
+
- current_worktree_path (optional): Report your current git worktree path (e.g., "../project-task-abc123")`,
|
|
36
38
|
end_work_session: `# end_work_session
|
|
37
39
|
End session and release claimed tasks.
|
|
38
40
|
|
|
@@ -629,7 +631,252 @@ Get cost breakdown by task for a project.
|
|
|
629
631
|
- limit: Max tasks to return (default: 20)
|
|
630
632
|
|
|
631
633
|
**Returns:** Tasks sorted by estimated cost with model breakdown`,
|
|
632
|
-
//
|
|
634
|
+
// Subtasks
|
|
635
|
+
add_subtask: `# add_subtask
|
|
636
|
+
Add a subtask to break down a larger task.
|
|
637
|
+
|
|
638
|
+
**Parameters:**
|
|
639
|
+
- parent_task_id (required): UUID of the parent task
|
|
640
|
+
- title (required): Subtask title
|
|
641
|
+
- description (optional): Detailed description
|
|
642
|
+
- priority (optional): 1-5 (defaults to parent priority)
|
|
643
|
+
- estimated_minutes (optional): Time estimate
|
|
644
|
+
|
|
645
|
+
**Note:** Max depth is 1 (subtasks cannot have their own subtasks).`,
|
|
646
|
+
get_subtasks: `# get_subtasks
|
|
647
|
+
Get subtasks for a parent task.
|
|
648
|
+
|
|
649
|
+
**Parameters:**
|
|
650
|
+
- parent_task_id (required): UUID of the parent task
|
|
651
|
+
- status (optional): Filter by status
|
|
652
|
+
|
|
653
|
+
**Returns:** Subtasks with aggregate completion stats.`,
|
|
654
|
+
// Bodies of work
|
|
655
|
+
create_body_of_work: `# create_body_of_work
|
|
656
|
+
Create a new body of work to group tasks into phases.
|
|
657
|
+
|
|
658
|
+
**Parameters:**
|
|
659
|
+
- project_id (required): Project UUID
|
|
660
|
+
- title (required): Title for the body of work
|
|
661
|
+
- description (optional): Description
|
|
662
|
+
- auto_deploy_on_completion (optional): Auto-deploy when all tasks complete (default: false)
|
|
663
|
+
- deploy_environment (optional): Target environment (default: production)
|
|
664
|
+
- deploy_version_bump (optional): Version bump (default: minor)
|
|
665
|
+
- deploy_trigger (optional): When to trigger auto-deploy (default: all_completed_validated)`,
|
|
666
|
+
update_body_of_work: `# update_body_of_work
|
|
667
|
+
Update a body of work's settings.
|
|
668
|
+
|
|
669
|
+
**Parameters:**
|
|
670
|
+
- body_of_work_id (required): Body of work UUID
|
|
671
|
+
- title, description (optional)
|
|
672
|
+
- auto_deploy_on_completion, deploy_environment, deploy_version_bump, deploy_trigger (optional)`,
|
|
673
|
+
get_body_of_work: `# get_body_of_work
|
|
674
|
+
Get a body of work with all its tasks organized by phase.
|
|
675
|
+
|
|
676
|
+
**Parameters:**
|
|
677
|
+
- body_of_work_id (required): Body of work UUID
|
|
678
|
+
|
|
679
|
+
**Returns:** Body of work with tasks grouped by pre/core/post phases.`,
|
|
680
|
+
get_bodies_of_work: `# get_bodies_of_work
|
|
681
|
+
List bodies of work for a project.
|
|
682
|
+
|
|
683
|
+
**Parameters:**
|
|
684
|
+
- project_id (required): Project UUID
|
|
685
|
+
- status (optional): Filter by status (draft, active, completed, cancelled)
|
|
686
|
+
- limit (optional): Max items (default 50)`,
|
|
687
|
+
delete_body_of_work: `# delete_body_of_work
|
|
688
|
+
Delete a body of work. Tasks are preserved but no longer grouped.
|
|
689
|
+
|
|
690
|
+
**Parameters:**
|
|
691
|
+
- body_of_work_id (required): Body of work UUID`,
|
|
692
|
+
add_task_to_body_of_work: `# add_task_to_body_of_work
|
|
693
|
+
Add a task to a body of work in a specific phase.
|
|
694
|
+
|
|
695
|
+
**Parameters:**
|
|
696
|
+
- body_of_work_id (required): Body of work UUID
|
|
697
|
+
- task_id (required): Task UUID to add
|
|
698
|
+
- phase (optional): pre, core, or post (default: core)
|
|
699
|
+
- order_index (optional): Order within phase`,
|
|
700
|
+
remove_task_from_body_of_work: `# remove_task_from_body_of_work
|
|
701
|
+
Remove a task from its body of work.
|
|
702
|
+
|
|
703
|
+
**Parameters:**
|
|
704
|
+
- task_id (required): Task UUID to remove
|
|
705
|
+
|
|
706
|
+
**Note:** The task is preserved, just no longer grouped.`,
|
|
707
|
+
activate_body_of_work: `# activate_body_of_work
|
|
708
|
+
Activate a draft body of work to start execution.
|
|
709
|
+
|
|
710
|
+
**Parameters:**
|
|
711
|
+
- body_of_work_id (required): Body of work UUID
|
|
712
|
+
|
|
713
|
+
**Note:** Requires at least one task. Once active, tasks follow phase order.`,
|
|
714
|
+
add_task_dependency: `# add_task_dependency
|
|
715
|
+
Add a dependency between tasks in a body of work.
|
|
716
|
+
|
|
717
|
+
**Parameters:**
|
|
718
|
+
- body_of_work_id (required): Body of work UUID
|
|
719
|
+
- task_id (required): Task that depends on another
|
|
720
|
+
- depends_on_task_id (required): Task that must complete first
|
|
721
|
+
|
|
722
|
+
**Note:** Prevents circular dependencies.`,
|
|
723
|
+
remove_task_dependency: `# remove_task_dependency
|
|
724
|
+
Remove a dependency between tasks.
|
|
725
|
+
|
|
726
|
+
**Parameters:**
|
|
727
|
+
- task_id (required): Task UUID
|
|
728
|
+
- depends_on_task_id (required): Dependency task UUID`,
|
|
729
|
+
get_task_dependencies: `# get_task_dependencies
|
|
730
|
+
Get task dependencies for a body of work or specific task.
|
|
731
|
+
|
|
732
|
+
**Parameters:**
|
|
733
|
+
- body_of_work_id (optional): Body of work UUID
|
|
734
|
+
- task_id (optional): Specific task UUID`,
|
|
735
|
+
get_next_body_of_work_task: `# get_next_body_of_work_task
|
|
736
|
+
Get the next available task from a body of work.
|
|
737
|
+
|
|
738
|
+
**Parameters:**
|
|
739
|
+
- body_of_work_id (required): Body of work UUID
|
|
740
|
+
|
|
741
|
+
**Note:** Considers phase order (pre → core → post) and dependencies.`,
|
|
742
|
+
// Sprints
|
|
743
|
+
create_sprint: `# create_sprint
|
|
744
|
+
Create a new sprint with time bounds and velocity tracking.
|
|
745
|
+
|
|
746
|
+
**Parameters:**
|
|
747
|
+
- project_id (required): Project UUID
|
|
748
|
+
- title (required): Sprint title (e.g., "Sprint 5")
|
|
749
|
+
- start_date (required): Start date (YYYY-MM-DD)
|
|
750
|
+
- end_date (required): End date (YYYY-MM-DD)
|
|
751
|
+
- goal (optional): Sprint goal statement
|
|
752
|
+
- auto_deploy_on_completion, deploy_environment, deploy_version_bump (optional)`,
|
|
753
|
+
update_sprint: `# update_sprint
|
|
754
|
+
Update a sprint's details.
|
|
755
|
+
|
|
756
|
+
**Parameters:**
|
|
757
|
+
- sprint_id (required): Sprint UUID
|
|
758
|
+
- title, goal, start_date, end_date (optional)
|
|
759
|
+
- auto_deploy_on_completion, deploy_environment, deploy_version_bump (optional)`,
|
|
760
|
+
get_sprint: `# get_sprint
|
|
761
|
+
Get a sprint with all its tasks organized by phase.
|
|
762
|
+
|
|
763
|
+
**Parameters:**
|
|
764
|
+
- sprint_id (required): Sprint UUID
|
|
765
|
+
|
|
766
|
+
**Returns:** Sprint with progress percentage, velocity points, committed points.`,
|
|
767
|
+
get_sprints: `# get_sprints
|
|
768
|
+
List sprints for a project with velocity metrics.
|
|
769
|
+
|
|
770
|
+
**Parameters:**
|
|
771
|
+
- project_id (required): Project UUID
|
|
772
|
+
- status (optional): planning, active, in_review, retrospective, completed, cancelled
|
|
773
|
+
- limit (optional): Max sprints (default 20)`,
|
|
774
|
+
delete_sprint: `# delete_sprint
|
|
775
|
+
Delete a sprint. Tasks are preserved but no longer grouped.
|
|
776
|
+
|
|
777
|
+
**Parameters:**
|
|
778
|
+
- sprint_id (required): Sprint UUID`,
|
|
779
|
+
start_sprint: `# start_sprint
|
|
780
|
+
Start a sprint. Transitions from 'planning' to 'active'.
|
|
781
|
+
|
|
782
|
+
**Parameters:**
|
|
783
|
+
- sprint_id (required): Sprint UUID
|
|
784
|
+
|
|
785
|
+
**Note:** Locks committed_points at current total story points.`,
|
|
786
|
+
complete_sprint: `# complete_sprint
|
|
787
|
+
Complete a sprint. Handles retrospective phase and auto-deployment.
|
|
788
|
+
|
|
789
|
+
**Parameters:**
|
|
790
|
+
- sprint_id (required): Sprint UUID
|
|
791
|
+
- retrospective_notes (optional): Sprint retrospective notes
|
|
792
|
+
- skip_retrospective (optional): Skip retrospective phase (default: false)`,
|
|
793
|
+
add_task_to_sprint: `# add_task_to_sprint
|
|
794
|
+
Add a task to a sprint with optional story points.
|
|
795
|
+
|
|
796
|
+
**Parameters:**
|
|
797
|
+
- sprint_id (required): Sprint UUID
|
|
798
|
+
- task_id (required): Task UUID to add
|
|
799
|
+
- story_points (optional): Story point estimate
|
|
800
|
+
- phase (optional): pre, core, or post (default: core)`,
|
|
801
|
+
remove_task_from_sprint: `# remove_task_from_sprint
|
|
802
|
+
Remove a task from a sprint.
|
|
803
|
+
|
|
804
|
+
**Parameters:**
|
|
805
|
+
- sprint_id (required): Sprint UUID
|
|
806
|
+
- task_id (required): Task UUID to remove
|
|
807
|
+
|
|
808
|
+
**Note:** Task returns to backlog.`,
|
|
809
|
+
get_sprint_backlog: `# get_sprint_backlog
|
|
810
|
+
Get tasks that can be added to a sprint.
|
|
811
|
+
|
|
812
|
+
**Parameters:**
|
|
813
|
+
- project_id (required): Project UUID
|
|
814
|
+
- sprint_id (optional): Exclude tasks already in this sprint
|
|
815
|
+
|
|
816
|
+
**Returns:** Tasks not assigned to any body of work or sprint.`,
|
|
817
|
+
get_sprint_velocity: `# get_sprint_velocity
|
|
818
|
+
Get velocity metrics for completed sprints.
|
|
819
|
+
|
|
820
|
+
**Parameters:**
|
|
821
|
+
- project_id (required): Project UUID
|
|
822
|
+
- limit (optional): Number of sprints to analyze (default 10)
|
|
823
|
+
|
|
824
|
+
**Returns:** Committed vs completed points, average velocity.`,
|
|
825
|
+
// Git issues
|
|
826
|
+
add_git_issue: `# add_git_issue
|
|
827
|
+
Record a git-related issue (merge conflict, push failure, etc.).
|
|
828
|
+
|
|
829
|
+
**Parameters:**
|
|
830
|
+
- project_id (required): Project UUID
|
|
831
|
+
- issue_type (required): merge_conflict, push_failed, rebase_needed, branch_diverged, pr_not_mergeable
|
|
832
|
+
- branch (required): Branch where the issue occurred
|
|
833
|
+
- target_branch, conflicting_files, error_message, pr_url, task_id (optional)`,
|
|
834
|
+
resolve_git_issue: `# resolve_git_issue
|
|
835
|
+
Mark a git issue as resolved.
|
|
836
|
+
|
|
837
|
+
**Parameters:**
|
|
838
|
+
- git_issue_id (required): Git issue UUID
|
|
839
|
+
- resolution_note (optional): How the issue was resolved
|
|
840
|
+
- auto_resolved (optional): Whether auto-resolved`,
|
|
841
|
+
get_git_issues: `# get_git_issues
|
|
842
|
+
Get git issues for a project.
|
|
843
|
+
|
|
844
|
+
**Parameters:**
|
|
845
|
+
- project_id (required): Project UUID
|
|
846
|
+
- status (optional): open or resolved (default: open)
|
|
847
|
+
- issue_type (optional): Filter by issue type
|
|
848
|
+
- branch (optional): Filter by branch
|
|
849
|
+
- limit (optional): Max issues (default 50)`,
|
|
850
|
+
delete_git_issue: `# delete_git_issue
|
|
851
|
+
Delete a git issue.
|
|
852
|
+
|
|
853
|
+
**Parameters:**
|
|
854
|
+
- git_issue_id (required): Git issue UUID`,
|
|
855
|
+
// Deployment requirements
|
|
856
|
+
add_deployment_requirement: `# add_deployment_requirement
|
|
857
|
+
Add a pre-deployment requirement.
|
|
858
|
+
|
|
859
|
+
**Parameters:**
|
|
860
|
+
- project_id (required): Project UUID
|
|
861
|
+
- type (required): migration, env_var, config, manual, breaking_change, agent_task
|
|
862
|
+
- title (required): Brief description
|
|
863
|
+
- description (optional): Detailed instructions
|
|
864
|
+
- stage (optional): preparation, deployment, or verification (default: preparation)
|
|
865
|
+
- file_path (optional): File path reference
|
|
866
|
+
- blocking (optional): Whether converted task blocks other work`,
|
|
867
|
+
complete_deployment_requirement: `# complete_deployment_requirement
|
|
868
|
+
Mark a deployment requirement as completed.
|
|
869
|
+
|
|
870
|
+
**Parameters:**
|
|
871
|
+
- requirement_id (required): Requirement UUID`,
|
|
872
|
+
get_deployment_requirements: `# get_deployment_requirements
|
|
873
|
+
Get pending deployment requirements.
|
|
874
|
+
|
|
875
|
+
**Parameters:**
|
|
876
|
+
- project_id (required): Project UUID
|
|
877
|
+
- stage (optional): preparation, deployment, verification, or all
|
|
878
|
+
- status (optional): pending, completed, converted_to_task, or all (default: pending)`,
|
|
879
|
+
// Knowledge base
|
|
633
880
|
query_knowledge_base: `# query_knowledge_base
|
|
634
881
|
Query aggregated project knowledge in a single call. Reduces token usage by combining multiple data sources.
|
|
635
882
|
|