wolfpack-mcp 1.0.76 → 1.0.78

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 CHANGED
@@ -232,7 +232,8 @@ Get a specific issue.
232
232
 
233
233
  #### `create_issue`
234
234
 
235
- Create a new issue.
235
+ Create a new issue. Human callers only — issues are how the people using the product report problems
236
+ they hit, so an agent files what it finds with `create_work_item` instead.
236
237
 
237
238
  - `title` (required): Issue title
238
239
  - `description`, `severity`, `type`, `assigned_to_id`, `environment`, `affected_version`, `reproducible`,
package/dist/index.js CHANGED
@@ -828,7 +828,8 @@ class WolfpackMCPServer {
828
828
  'Returns full details including description (markdown notes). ' +
829
829
  'Call this before updating to see current content. ' +
830
830
  'WORKFLOW: When asked to work on an item, check its status and follow the required state transitions ' +
831
- '(pending→pull first, new→doing, blocked/ready/completed/closednew→doing, then review when done). ' +
831
+ '(pending→pull first, new→doing, review→doing when you are picking the work back up, ' +
832
+ 'blocked/ready/completed/closed→new→doing, then review when done). ' +
832
833
  '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. ' +
833
834
  '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. ' +
834
835
  'IMAGES: Image references in the description (e.g. `![alt](/api/files/...)`) can be viewed using the download_image tool.',
@@ -850,7 +851,7 @@ class WolfpackMCPServer {
850
851
  {
851
852
  name: 'update_work_progress',
852
853
  description: 'Update work item description/notes with your progress. WORKFLOW: 1) get_work_item to read current notes 2) Modify the markdown description with new findings/progress 3) Call this with the complete updated description. The full description replaces the existing one. ' +
853
- 'STATUS: Items in "new" are auto-advanced to "doing" (updating progress means work has started). Completing the work is NOT auto-detected: when done, set status to "review" via update_work_item and add a completion comment. ' +
854
+ 'STATUS: Items in "new" — and items in "review" you are picking back up — are auto-advanced to "doing" (recording progress means work is under way). Completing the work is NOT auto-detected: when done, set status to "review" via update_work_item and add a completion comment. ' +
854
855
  'CRITICAL: NEVER overwrite or remove the original description text. Preserve all existing content exactly as-is. Append your plan below a "---" separator. You may only modify content you previously added (your plan section). ' +
855
856
  'BEST PRACTICE: Append a plan with markdown checkboxes (- [ ] task). Check off completed tasks (- [x] task) as you progress. Include sections for: Plan (checklist), Approach (strategy), and Notes (discoveries/decisions). ' +
856
857
  CONTENT_LINKING_HELP,
@@ -876,8 +877,12 @@ class WolfpackMCPServer {
876
877
  'Supports: title, description, status, leading_user_id (assignee), assisting_user1/2/3_id, ' +
877
878
  'radar_item_id (initiative), category_id, priority (0-4), size (S/M/L), work_pool_id, tags, and closing_comment. ' +
878
879
  'STATUS WORKFLOW: "pending" (backlog) → "new" (to do) → "doing" (in progress) → "review" (work done) → "ready" (awaiting deployment) → "completed" (deployed). ' +
879
- 'Use "blocked" when work cannot proceed. For "pending" items use pull_work_item first. ' +
880
+ 'Use "blocked" when work cannot proceed. AGENTS: you cannot start un-started work here — ' +
881
+ 'a status change on a "pending" or "new" item that is not assigned to you is refused. ' +
882
+ 'Take it with pull_work_item, which assigns it to you and puts it in "doing"; that is ' +
883
+ 'what makes the board show who is working on what. ' +
880
884
  'When moving to "review", add a completion comment via create_work_item_comment. When moving to "blocked", add a comment explaining the blocker. ' +
885
+ 'When you take an item back out of "review" to rework it, set it to "doing" first — an item being changed is not an item waiting to be reviewed. ' +
881
886
  'closing_comment is only accepted together with status "closed" — never use it for progress or completion notes.',
882
887
  inputSchema: {
883
888
  type: 'object',
@@ -911,7 +916,7 @@ class WolfpackMCPServer {
911
916
  },
912
917
  leading_user_id: {
913
918
  type: ['string', 'null'],
914
- description: 'User ID to assign as leading user, or null to unassign',
919
+ description: "User ID to assign as leading user, or null to unassign. Agents may not assign work to themselves — that is the product owner's decision.",
915
920
  },
916
921
  radar_item_id: {
917
922
  type: ['string', 'null'],
@@ -966,15 +971,17 @@ class WolfpackMCPServer {
966
971
  },
967
972
  {
968
973
  name: 'pull_work_item',
969
- description: 'Pull a specific work item from the backlog to the board. ' +
970
- 'REQUIRED: Use this when starting work on a "pending" (backlog) item. ' +
971
- 'This claims the item (assigns to you) and sets status to "new". ' +
974
+ description: 'Pull a specific work item from the backlog to the board, or claim one already on it. ' +
975
+ 'REQUIRED: Use this when starting work on a "pending" (backlog) item, and to claim an ' +
976
+ 'unassigned "new" (board) item approved board work is picked up just like approved ' +
977
+ 'backlog work. This claims the item (assigns to you); a backlog item also moves to "new". ' +
972
978
  'AGENTS: an item already assigned to you is always pullable, approved or not. An item ' +
973
979
  'that is NOT assigned to you is pullable only if it is routed to a work pool you belong ' +
974
980
  'to AND a human has approved it (approved=true) — pool membership grants the access, ' +
975
981
  'approval grants the go-ahead. An unassigned item in no work pool cannot be pulled by an ' +
976
982
  'agent and will return 403: ask a human to route it to your pool or assign it to you. ' +
977
- 'After pulling, move to "doing" to indicate active work, then "review" when done. ' +
983
+ 'AGENTS: pulling puts the item straight into "doing" you are taking it to start on it ' +
984
+ 'now — so there is no separate "move it to doing" step. Move it to "review" when done. ' +
978
985
  'If no assignee is specified, assigns to the API key owner. ' +
979
986
  'In personal projects, items are always assigned to the owner.',
980
987
  inputSchema: {
@@ -982,7 +989,7 @@ class WolfpackMCPServer {
982
989
  properties: {
983
990
  work_item_id: {
984
991
  type: 'string',
985
- description: 'The ID of the work item to pull from backlog',
992
+ description: 'The ID of the work item to pull or claim',
986
993
  },
987
994
  leading_user_id: {
988
995
  type: 'string',
@@ -1209,6 +1216,7 @@ class WolfpackMCPServer {
1209
1216
  {
1210
1217
  name: 'create_work_item',
1211
1218
  description: 'Create a new work item in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:work_items:create permission. ' +
1219
+ 'Agents: work you file lands unassigned in the backlog, whatever status you ask for, and waits there for the product owner to approve and assign it. ' +
1212
1220
  CONTENT_LINKING_HELP,
1213
1221
  inputSchema: {
1214
1222
  type: 'object',
@@ -1248,7 +1256,7 @@ class WolfpackMCPServer {
1248
1256
  },
1249
1257
  leading_user_id: {
1250
1258
  type: 'string',
1251
- description: 'User ID to assign as leading user',
1259
+ description: "User ID to assign as leading user. Agents may not assign work to themselves — that is the product owner's decision.",
1252
1260
  },
1253
1261
  category_id: {
1254
1262
  type: 'string',
@@ -1265,6 +1273,7 @@ class WolfpackMCPServer {
1265
1273
  {
1266
1274
  name: 'create_issue',
1267
1275
  description: 'Create a new issue in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:issues:create permission. ' +
1276
+ 'Agents: not for you. Issues are how the people using the product report problems they hit — file what you found with create_work_item instead. ' +
1268
1277
  CONTENT_LINKING_HELP,
1269
1278
  inputSchema: {
1270
1279
  type: 'object',
@@ -2130,12 +2139,16 @@ class WolfpackMCPServer {
2130
2139
  let workItem = await this.client.updateWorkProgress(parsed.work_item_id, parsed.description, teamSlug);
2131
2140
  if (workItem) {
2132
2141
  let summary = `Updated description on: ${workItem.title}`;
2133
- // Progress on a "new" item means work has started advance it to "doing"
2134
- if (workItem.status === 'new') {
2135
- const advanced = await this.client.updateWorkItem(parsed.work_item_id, { status: 'doing' }, teamSlug);
2142
+ // Recording progress means the work is under way: a "new" item starts, and an
2143
+ // item in "review" comes back to "doing" because its developer is working on it
2144
+ // again (#1787) otherwise the board keeps showing handed-over work that is
2145
+ // still being changed.
2146
+ const previousStatus = workItem.status;
2147
+ if (previousStatus === 'new' || previousStatus === 'review') {
2148
+ const advanced = await this.moveToDoing(parsed.work_item_id, teamSlug);
2136
2149
  if (advanced) {
2137
2150
  workItem = advanced;
2138
- summary += ' (status auto-advanced new → doing)';
2151
+ summary += ` (status auto-advanced ${previousStatus} → doing)`;
2139
2152
  }
2140
2153
  }
2141
2154
  let text = `${summary}\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`;
@@ -2265,7 +2278,7 @@ class WolfpackMCPServer {
2265
2278
  content: [
2266
2279
  {
2267
2280
  type: 'text',
2268
- text: `Pulled "${workItem.title}" from backlog to board (status: new)\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
2281
+ text: `Claimed "${workItem.title}" (status: ${workItem.status})\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
2269
2282
  },
2270
2283
  ],
2271
2284
  };
@@ -2965,6 +2978,24 @@ class WolfpackMCPServer {
2965
2978
  }
2966
2979
  });
2967
2980
  }
2981
+ /**
2982
+ * Put a work item in "doing" after progress was recorded on it, and report whether that
2983
+ * stuck. An agent whose work pool may not set "doing" — a reviewer annotating an item in
2984
+ * "review" rather than the developer resuming it — is refused by the backend status
2985
+ * policy; that refusal is the right answer, so it leaves the saved note alone instead of
2986
+ * failing the call the agent actually made.
2987
+ */
2988
+ async moveToDoing(workItemId, teamSlug) {
2989
+ try {
2990
+ return await this.client.updateWorkItem(workItemId, { status: 'doing' }, teamSlug);
2991
+ }
2992
+ catch (error) {
2993
+ if (error && typeof error === 'object' && 'status' in error && error.status === 403) {
2994
+ return null;
2995
+ }
2996
+ throw error;
2997
+ }
2998
+ }
2968
2999
  isImageBuffer(buffer) {
2969
3000
  if (buffer.length < 4)
2970
3001
  return false;
@@ -25,6 +25,9 @@ const STATUS_REMINDERS = {
25
25
  'BEFORE starting work.',
26
26
  doing: 'REMINDER: This work item is in "doing". The moment the work is complete, set status to "review" ' +
27
27
  '(update_work_item) and add a completion comment — do not leave it sitting in "doing".',
28
+ review: 'REMINDER: This work item is in "review" — the work was handed over. If you are picking it back ' +
29
+ 'up (rework, review feedback, a follow-up change), set status to "doing" (update_work_item) BEFORE ' +
30
+ 'starting, so the board shows the work is under way again. If you are reviewing it, leave it where it is.',
28
31
  };
29
32
  // Reminders to prepend to a get_work_item response, most urgent first.
30
33
  export function getWorkItemReminders(status, description, approved) {
@@ -50,13 +50,18 @@ describe('getWorkItemReminders', () => {
50
50
  expect.stringContaining('set status to "review"'),
51
51
  ]);
52
52
  });
53
+ it('tells agents picking a reviewed item back up to move it to doing', () => {
54
+ const reminders = getWorkItemReminders('review', PLAN);
55
+ expect(reminders).toEqual([expect.stringContaining('set status to "doing"')]);
56
+ expect(reminders[0]).toContain('If you are reviewing it, leave it where it is');
57
+ });
53
58
  it('adds the no-plan reminder when the description has no plan', () => {
54
59
  const reminders = getWorkItemReminders('new', 'Just a description');
55
60
  expect(reminders).toHaveLength(2);
56
61
  expect(reminders[1]).toContain('no plan');
57
62
  });
58
63
  it('stays quiet for statuses with no required action', () => {
59
- expect(getWorkItemReminders('review', PLAN)).toEqual([]);
60
64
  expect(getWorkItemReminders('completed', PLAN)).toEqual([]);
65
+ expect(getWorkItemReminders('ready', PLAN)).toEqual([]);
61
66
  });
62
67
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolfpack-mcp",
3
- "version": "1.0.76",
3
+ "version": "1.0.78",
4
4
  "description": "MCP server for Wolfpack AI-enhanced software delivery tools",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",