wolfpack-mcp 1.0.37 → 1.0.38
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/dist/apiClient.js +16 -6
- package/dist/client.js +24 -0
- package/dist/index.js +98 -0
- package/package.json +1 -1
package/dist/apiClient.js
CHANGED
|
@@ -8,6 +8,16 @@ export class ApiError extends Error {
|
|
|
8
8
|
this.name = 'ApiError';
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
+
function formatError(error) {
|
|
12
|
+
if (error instanceof Error) {
|
|
13
|
+
const code = error.code;
|
|
14
|
+
if (code)
|
|
15
|
+
return `${error.message} (${code})`;
|
|
16
|
+
if (error.message)
|
|
17
|
+
return error.message;
|
|
18
|
+
}
|
|
19
|
+
return String(error) || 'unknown error';
|
|
20
|
+
}
|
|
11
21
|
export class ApiClient {
|
|
12
22
|
headers = {
|
|
13
23
|
Authorization: `Bearer ${config.apiKey}`,
|
|
@@ -30,7 +40,7 @@ export class ApiClient {
|
|
|
30
40
|
if (error instanceof ApiError) {
|
|
31
41
|
throw error;
|
|
32
42
|
}
|
|
33
|
-
throw new Error(`Failed to GET ${path}: ${error}`);
|
|
43
|
+
throw new Error(`Failed to GET ${path}: ${formatError(error)}`);
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
async post(path, body) {
|
|
@@ -51,7 +61,7 @@ export class ApiClient {
|
|
|
51
61
|
if (error instanceof ApiError) {
|
|
52
62
|
throw error;
|
|
53
63
|
}
|
|
54
|
-
throw new Error(`Failed to POST ${path}: ${error}`);
|
|
64
|
+
throw new Error(`Failed to POST ${path}: ${formatError(error)}`);
|
|
55
65
|
}
|
|
56
66
|
}
|
|
57
67
|
async put(path, body) {
|
|
@@ -72,7 +82,7 @@ export class ApiClient {
|
|
|
72
82
|
if (error instanceof ApiError) {
|
|
73
83
|
throw error;
|
|
74
84
|
}
|
|
75
|
-
throw new Error(`Failed to PUT ${path}: ${error}`);
|
|
85
|
+
throw new Error(`Failed to PUT ${path}: ${formatError(error)}`);
|
|
76
86
|
}
|
|
77
87
|
}
|
|
78
88
|
async patch(path, body) {
|
|
@@ -93,7 +103,7 @@ export class ApiClient {
|
|
|
93
103
|
if (error instanceof ApiError) {
|
|
94
104
|
throw error;
|
|
95
105
|
}
|
|
96
|
-
throw new Error(`Failed to PATCH ${path}: ${error}`);
|
|
106
|
+
throw new Error(`Failed to PATCH ${path}: ${formatError(error)}`);
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
109
|
async getBuffer(path) {
|
|
@@ -119,7 +129,7 @@ export class ApiClient {
|
|
|
119
129
|
if (error instanceof ApiError) {
|
|
120
130
|
throw error;
|
|
121
131
|
}
|
|
122
|
-
throw new Error(`Failed to GET buffer ${path}: ${error}`);
|
|
132
|
+
throw new Error(`Failed to GET buffer ${path}: ${formatError(error)}`);
|
|
123
133
|
}
|
|
124
134
|
}
|
|
125
135
|
async postMultipart(path, buffer, filename, mimeType) {
|
|
@@ -166,7 +176,7 @@ export class ApiClient {
|
|
|
166
176
|
if (error instanceof ApiError) {
|
|
167
177
|
throw error;
|
|
168
178
|
}
|
|
169
|
-
throw new Error(`Failed to DELETE ${path}: ${error}`);
|
|
179
|
+
throw new Error(`Failed to DELETE ${path}: ${formatError(error)}`);
|
|
170
180
|
}
|
|
171
181
|
}
|
|
172
182
|
}
|
package/dist/client.js
CHANGED
|
@@ -202,6 +202,17 @@ export class WolfpackClient {
|
|
|
202
202
|
throw error;
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
|
+
async updateWorkItemInitiative(workItemId, radarItemId) {
|
|
206
|
+
try {
|
|
207
|
+
return await this.api.put(`/work-items/${workItemId}/initiative`, { radarItemId });
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
205
216
|
async pullWorkItem(workItemId, data) {
|
|
206
217
|
try {
|
|
207
218
|
return await this.api.post(`/work-items/${workItemId}/pull`, data || {});
|
|
@@ -213,6 +224,19 @@ export class WolfpackClient {
|
|
|
213
224
|
throw error;
|
|
214
225
|
}
|
|
215
226
|
}
|
|
227
|
+
async submitWorkItemForm(workItemId, formValues) {
|
|
228
|
+
try {
|
|
229
|
+
return await this.api.put(`/work-items/${workItemId}/form`, {
|
|
230
|
+
formValues,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
216
240
|
// Radar Item (Initiative/Roadmap) methods
|
|
217
241
|
async listRadarItems(options) {
|
|
218
242
|
const params = new URLSearchParams();
|
package/dist/index.js
CHANGED
|
@@ -117,6 +117,13 @@ const UpdateWorkItemTitleSchema = z.object({
|
|
|
117
117
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
118
118
|
title: z.string().describe('New title for the work item'),
|
|
119
119
|
});
|
|
120
|
+
const UpdateWorkItemInitiativeSchema = z.object({
|
|
121
|
+
work_item_id: z.string().describe('The ID of the work item'),
|
|
122
|
+
radar_item_id: z
|
|
123
|
+
.string()
|
|
124
|
+
.nullable()
|
|
125
|
+
.describe('Radar/initiative item ID to link to, or null to unlink'),
|
|
126
|
+
});
|
|
120
127
|
const PullWorkItemSchema = z.object({
|
|
121
128
|
work_item_id: z.string().describe('The ID of the work item to pull from backlog'),
|
|
122
129
|
leading_user_id: z
|
|
@@ -124,6 +131,10 @@ const PullWorkItemSchema = z.object({
|
|
|
124
131
|
.optional()
|
|
125
132
|
.describe('User ID to assign as leading user (defaults to API key owner)'),
|
|
126
133
|
});
|
|
134
|
+
const SubmitWorkItemFormSchema = z.object({
|
|
135
|
+
work_item_id: z.string().describe('The ID of the work item'),
|
|
136
|
+
form_values: z.record(z.any()).describe('Key-value pairs matching formDefinition field names'),
|
|
137
|
+
});
|
|
127
138
|
// Radar Item (Initiative/Roadmap) schemas
|
|
128
139
|
const ListRadarItemsSchema = z.object({
|
|
129
140
|
project_slug: z.string().optional().describe('Project slug to filter radar items'),
|
|
@@ -189,6 +200,10 @@ const CreateWorkItemSchema = z.object({
|
|
|
189
200
|
.optional()
|
|
190
201
|
.describe('Initial status: "pending" (backlog), "new" (to do), "doing", "review", "ready", "blocked", "completed". Defaults to "new".'),
|
|
191
202
|
priority: z.number().optional().describe('Priority level (0-4, higher is more important)'),
|
|
203
|
+
size: z
|
|
204
|
+
.enum(['S', 'M', 'L'])
|
|
205
|
+
.optional()
|
|
206
|
+
.describe('Size estimate: "S" (small), "M" (medium), "L" (large)'),
|
|
192
207
|
leading_user_id: z.string().optional().describe('User ID to assign as leading user'),
|
|
193
208
|
category_id: z.string().optional().describe('Category ID to organize the work item'),
|
|
194
209
|
radar_item_id: z.string().optional().describe('Radar/initiative item ID to link to'),
|
|
@@ -448,6 +463,7 @@ class WolfpackMCPServer {
|
|
|
448
463
|
'WORKFLOW: When asked to work on an item, check its status and follow the required state transitions ' +
|
|
449
464
|
'(pending→pull first, new→doing, blocked/ready/completed/closed→new→doing, then review when done). ' +
|
|
450
465
|
'PLANNING: Check if the description contains a plan (markdown checklist). If not, APPEND one using update_work_progress - preserve all original description text and add your plan below a "---" separator. ' +
|
|
466
|
+
'FORMS: Procedure-created work items may include formDefinition (field definitions with name, label, type, required, options) and formValues (current values). Use submit_work_item_form to fill in form values. ' +
|
|
451
467
|
'IMAGES: Image references in the description (e.g. ``) can be viewed using the download_image tool.',
|
|
452
468
|
inputSchema: {
|
|
453
469
|
type: 'object',
|
|
@@ -557,6 +573,25 @@ class WolfpackMCPServer {
|
|
|
557
573
|
required: ['work_item_id', 'title'],
|
|
558
574
|
},
|
|
559
575
|
},
|
|
576
|
+
{
|
|
577
|
+
name: 'update_work_item_initiative',
|
|
578
|
+
description: 'Link or unlink a work item to/from a radar item (initiative). ' +
|
|
579
|
+
'Pass a radar_item_id to link, or null to remove the initiative link.',
|
|
580
|
+
inputSchema: {
|
|
581
|
+
type: 'object',
|
|
582
|
+
properties: {
|
|
583
|
+
work_item_id: {
|
|
584
|
+
type: 'string',
|
|
585
|
+
description: 'The ID of the work item',
|
|
586
|
+
},
|
|
587
|
+
radar_item_id: {
|
|
588
|
+
type: ['string', 'null'],
|
|
589
|
+
description: 'Radar/initiative item ID to link to, or null to unlink',
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
required: ['work_item_id', 'radar_item_id'],
|
|
593
|
+
},
|
|
594
|
+
},
|
|
560
595
|
{
|
|
561
596
|
name: 'pull_work_item',
|
|
562
597
|
description: 'Pull a specific work item from the backlog to the board. ' +
|
|
@@ -580,6 +615,26 @@ class WolfpackMCPServer {
|
|
|
580
615
|
required: ['work_item_id'],
|
|
581
616
|
},
|
|
582
617
|
},
|
|
618
|
+
{
|
|
619
|
+
name: 'submit_work_item_form',
|
|
620
|
+
description: 'Submit form values for a procedure-created work item. ' +
|
|
621
|
+
'Use get_work_item first to see formDefinition (field names, types, required) and current formValues. ' +
|
|
622
|
+
'Then call this with form_values mapping field names to values.',
|
|
623
|
+
inputSchema: {
|
|
624
|
+
type: 'object',
|
|
625
|
+
properties: {
|
|
626
|
+
work_item_id: {
|
|
627
|
+
type: 'string',
|
|
628
|
+
description: 'The ID of the work item',
|
|
629
|
+
},
|
|
630
|
+
form_values: {
|
|
631
|
+
type: 'object',
|
|
632
|
+
description: 'Key-value pairs matching formDefinition field names',
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
required: ['work_item_id', 'form_values'],
|
|
636
|
+
},
|
|
637
|
+
},
|
|
583
638
|
// Radar Item (Initiative/Roadmap) tools
|
|
584
639
|
{
|
|
585
640
|
name: 'list_radar_items',
|
|
@@ -737,6 +792,11 @@ class WolfpackMCPServer {
|
|
|
737
792
|
type: 'number',
|
|
738
793
|
description: 'Priority level (0-4, higher is more important)',
|
|
739
794
|
},
|
|
795
|
+
size: {
|
|
796
|
+
type: 'string',
|
|
797
|
+
enum: ['S', 'M', 'L'],
|
|
798
|
+
description: 'Size estimate: "S" (small), "M" (medium), "L" (large)',
|
|
799
|
+
},
|
|
740
800
|
leading_user_id: {
|
|
741
801
|
type: 'string',
|
|
742
802
|
description: 'User ID to assign as leading user',
|
|
@@ -1223,6 +1283,26 @@ class WolfpackMCPServer {
|
|
|
1223
1283
|
content: [{ type: 'text', text: 'Work item not found' }],
|
|
1224
1284
|
};
|
|
1225
1285
|
}
|
|
1286
|
+
case 'update_work_item_initiative': {
|
|
1287
|
+
const parsed = UpdateWorkItemInitiativeSchema.parse(args);
|
|
1288
|
+
const workItem = await this.client.updateWorkItemInitiative(parsed.work_item_id, parsed.radar_item_id);
|
|
1289
|
+
if (workItem) {
|
|
1290
|
+
const initiativeText = parsed.radar_item_id
|
|
1291
|
+
? `linked to initiative ${parsed.radar_item_id}`
|
|
1292
|
+
: 'unlinked from initiative';
|
|
1293
|
+
return {
|
|
1294
|
+
content: [
|
|
1295
|
+
{
|
|
1296
|
+
type: 'text',
|
|
1297
|
+
text: `Updated "${workItem.title}" - ${initiativeText}\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1298
|
+
},
|
|
1299
|
+
],
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
return {
|
|
1303
|
+
content: [{ type: 'text', text: 'Work item not found' }],
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1226
1306
|
case 'pull_work_item': {
|
|
1227
1307
|
const parsed = PullWorkItemSchema.parse(args);
|
|
1228
1308
|
const workItem = await this.client.pullWorkItem(parsed.work_item_id, {
|
|
@@ -1242,6 +1322,23 @@ class WolfpackMCPServer {
|
|
|
1242
1322
|
content: [{ type: 'text', text: 'Work item not found' }],
|
|
1243
1323
|
};
|
|
1244
1324
|
}
|
|
1325
|
+
case 'submit_work_item_form': {
|
|
1326
|
+
const parsed = SubmitWorkItemFormSchema.parse(args);
|
|
1327
|
+
const workItem = await this.client.submitWorkItemForm(parsed.work_item_id, parsed.form_values);
|
|
1328
|
+
if (workItem) {
|
|
1329
|
+
return {
|
|
1330
|
+
content: [
|
|
1331
|
+
{
|
|
1332
|
+
type: 'text',
|
|
1333
|
+
text: `Submitted form values for "${workItem.title}"\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1334
|
+
},
|
|
1335
|
+
],
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
return {
|
|
1339
|
+
content: [{ type: 'text', text: 'Work item not found' }],
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1245
1342
|
// Radar Item handlers
|
|
1246
1343
|
case 'list_radar_items': {
|
|
1247
1344
|
const parsed = ListRadarItemsSchema.parse(args);
|
|
@@ -1317,6 +1414,7 @@ class WolfpackMCPServer {
|
|
|
1317
1414
|
description: parsed.description,
|
|
1318
1415
|
status: parsed.status,
|
|
1319
1416
|
priority: parsed.priority,
|
|
1417
|
+
size: parsed.size,
|
|
1320
1418
|
leadingUserId: parsed.leading_user_id,
|
|
1321
1419
|
categoryId: parsed.category_id,
|
|
1322
1420
|
radarItemId: parsed.radar_item_id,
|