wolfpack-mcp 1.0.65 → 1.0.66
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/client.js +2 -0
- package/dist/index.js +13 -1
- package/dist/workItemReminders.js +11 -4
- package/dist/workItemReminders.test.js +10 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -154,6 +154,8 @@ export class WolfpackClient {
|
|
|
154
154
|
params.append('dateFrom', options.dateFrom);
|
|
155
155
|
if (options?.dateTo)
|
|
156
156
|
params.append('dateTo', options.dateTo);
|
|
157
|
+
if (options?.approved)
|
|
158
|
+
params.append('approved', options.approved);
|
|
157
159
|
// If explicit limit/offset provided, use single request (for manual pagination)
|
|
158
160
|
if (options?.limit !== undefined || options?.offset !== undefined) {
|
|
159
161
|
if (options?.limit)
|
package/dist/index.js
CHANGED
|
@@ -97,6 +97,10 @@ const ListWorkItemsSchema = z.object({
|
|
|
97
97
|
.string()
|
|
98
98
|
.optional()
|
|
99
99
|
.describe('Filter items created on or before this date (ISO format, e.g. "2025-12-31")'),
|
|
100
|
+
approved: z.coerce
|
|
101
|
+
.string()
|
|
102
|
+
.optional()
|
|
103
|
+
.describe('Filter by approval: "true" for approved items, "false" for not-yet-approved. Backlog items must be approved before agents may pull them.'),
|
|
100
104
|
limit: z.number().optional().describe('Maximum number of items to return'),
|
|
101
105
|
offset: z.number().optional().describe('Number of items to skip'),
|
|
102
106
|
});
|
|
@@ -798,6 +802,11 @@ class WolfpackMCPServer {
|
|
|
798
802
|
type: 'string',
|
|
799
803
|
description: 'Filter items created on or before this date (ISO format, e.g. "2025-12-31")',
|
|
800
804
|
},
|
|
805
|
+
approved: {
|
|
806
|
+
type: 'string',
|
|
807
|
+
description: 'Filter by approval: "true" for approved items, "false" for not-yet-approved. ' +
|
|
808
|
+
'Backlog ("pending") items must be approved by a human before agents may pull them.',
|
|
809
|
+
},
|
|
801
810
|
limit: { type: 'number', description: 'Maximum number of items to return' },
|
|
802
811
|
offset: { type: 'number', description: 'Number of items to skip' },
|
|
803
812
|
},
|
|
@@ -944,6 +953,8 @@ class WolfpackMCPServer {
|
|
|
944
953
|
description: 'Pull a specific work item from the backlog to the board. ' +
|
|
945
954
|
'REQUIRED: Use this when starting work on a "pending" (backlog) item. ' +
|
|
946
955
|
'This claims the item (assigns to you) and sets status to "new". ' +
|
|
956
|
+
'APPROVAL: Agents can only pull backlog items a human has approved (approved=true on the item) — ' +
|
|
957
|
+
'unapproved items must stay in the backlog until a human approves them. ' +
|
|
947
958
|
'After pulling, move to "doing" to indicate active work, then "review" when done. ' +
|
|
948
959
|
'If no assignee is specified, assigns to the API key owner. ' +
|
|
949
960
|
'In personal projects, items are always assigned to the owner.',
|
|
@@ -2062,6 +2073,7 @@ class WolfpackMCPServer {
|
|
|
2062
2073
|
sortOrder: parsed.sort_order,
|
|
2063
2074
|
dateFrom: parsed.date_from,
|
|
2064
2075
|
dateTo: parsed.date_to,
|
|
2076
|
+
approved: parsed.approved,
|
|
2065
2077
|
limit: parsed.limit,
|
|
2066
2078
|
offset: parsed.offset,
|
|
2067
2079
|
});
|
|
@@ -2078,7 +2090,7 @@ class WolfpackMCPServer {
|
|
|
2078
2090
|
const workItem = await this.client.getWorkItem(parsed.work_item_id, parsed.project_slug || this.client.getProjectSlug() || undefined);
|
|
2079
2091
|
if (workItem) {
|
|
2080
2092
|
let text = JSON.stringify(stripUuids(workItem), null, 2);
|
|
2081
|
-
const reminders = getWorkItemReminders(workItem.status, workItem.description);
|
|
2093
|
+
const reminders = getWorkItemReminders(workItem.status, workItem.description, workItem.approved);
|
|
2082
2094
|
if (reminders.length > 0) {
|
|
2083
2095
|
text = `${reminders.join('\n\n')}\n\n${text}`;
|
|
2084
2096
|
}
|
|
@@ -27,11 +27,18 @@ const STATUS_REMINDERS = {
|
|
|
27
27
|
'(update_work_item) and add a completion comment — do not leave it sitting in "doing".',
|
|
28
28
|
};
|
|
29
29
|
// Reminders to prepend to a get_work_item response, most urgent first.
|
|
30
|
-
export function getWorkItemReminders(status, description) {
|
|
30
|
+
export function getWorkItemReminders(status, description, approved) {
|
|
31
31
|
const reminders = [];
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
reminders.push(
|
|
32
|
+
if (status === 'pending' && approved === false) {
|
|
33
|
+
// Overrides the generic pending reminder: pulling would be refused anyway
|
|
34
|
+
reminders.push('REMINDER: This backlog item has NOT been approved. Agents may not pull it — ' +
|
|
35
|
+
'leave it in the backlog until a human approves it.');
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const statusReminder = STATUS_REMINDERS[status];
|
|
39
|
+
if (statusReminder)
|
|
40
|
+
reminders.push(statusReminder);
|
|
41
|
+
}
|
|
35
42
|
if (!hasPlan(description)) {
|
|
36
43
|
reminders.push('REMINDER: This work item has no plan. Before starting work, use update_work_progress to add a plan ' +
|
|
37
44
|
'below a "---" separator. Preserve the original description and append your plan with markdown ' +
|
|
@@ -30,6 +30,16 @@ describe('getWorkItemReminders', () => {
|
|
|
30
30
|
expect.stringContaining('pull_work_item'),
|
|
31
31
|
]);
|
|
32
32
|
});
|
|
33
|
+
it('still tells agents to pull approved pending items', () => {
|
|
34
|
+
expect(getWorkItemReminders('pending', PLAN, true)).toEqual([
|
|
35
|
+
expect.stringContaining('pull_work_item'),
|
|
36
|
+
]);
|
|
37
|
+
});
|
|
38
|
+
it('warns agents off unapproved pending items instead of telling them to pull', () => {
|
|
39
|
+
expect(getWorkItemReminders('pending', PLAN, false)).toEqual([
|
|
40
|
+
expect.stringContaining('NOT been approved'),
|
|
41
|
+
]);
|
|
42
|
+
});
|
|
33
43
|
it('tells agents to move new items to doing', () => {
|
|
34
44
|
expect(getWorkItemReminders('new', PLAN)).toEqual([
|
|
35
45
|
expect.stringContaining('set status to "doing"'),
|