wolfpack-mcp 1.0.62 → 1.0.64

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.
@@ -0,0 +1,41 @@
1
+ // Workflow reminders injected into work-item tool responses. Tool descriptions document
2
+ // the status workflow, but agents skim them — a reminder in the response at the moment of
3
+ // action is what reliably changes behaviour. Reminders only fire when actionable.
4
+ // Detect if a work item description contains a plan
5
+ export function hasPlan(description) {
6
+ if (!description)
7
+ return false;
8
+ // Check for markdown checklist items (plan indicators)
9
+ if (/- \[[ x]\]/.test(description))
10
+ return true;
11
+ // Check for --- separator with content after (agent-added section)
12
+ if (/\n---\n/.test(description))
13
+ return true;
14
+ return false;
15
+ }
16
+ // True when the description has a checklist and every task is checked off.
17
+ export function allTasksChecked(description) {
18
+ if (!description)
19
+ return false;
20
+ return /- \[x\]/.test(description) && !/- \[ \]/.test(description);
21
+ }
22
+ const STATUS_REMINDERS = {
23
+ pending: 'REMINDER: This work item is in the backlog ("pending"). Claim it with pull_work_item before starting work.',
24
+ new: 'REMINDER: This work item is in "new". If you are picking it up, set status to "doing" (update_work_item) ' +
25
+ 'BEFORE starting work.',
26
+ doing: 'REMINDER: This work item is in "doing". The moment the work is complete, set status to "review" ' +
27
+ '(update_work_item) and add a completion comment — do not leave it sitting in "doing".',
28
+ };
29
+ // Reminders to prepend to a get_work_item response, most urgent first.
30
+ export function getWorkItemReminders(status, description) {
31
+ const reminders = [];
32
+ const statusReminder = STATUS_REMINDERS[status];
33
+ if (statusReminder)
34
+ reminders.push(statusReminder);
35
+ if (!hasPlan(description)) {
36
+ reminders.push('REMINDER: This work item has no plan. Before starting work, use update_work_progress to add a plan ' +
37
+ 'below a "---" separator. Preserve the original description and append your plan with markdown ' +
38
+ 'checkboxes (- [ ] task).');
39
+ }
40
+ return reminders;
41
+ }
@@ -0,0 +1,52 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { hasPlan, allTasksChecked, getWorkItemReminders } from './workItemReminders.js';
3
+ const PLAN = 'Original text\n\n---\n\n## Plan\n\n- [x] first task\n- [ ] second task';
4
+ const DONE_PLAN = 'Original text\n\n---\n\n## Plan\n\n- [x] first task\n- [x] second task';
5
+ describe('hasPlan', () => {
6
+ it('detects markdown checklists', () => {
7
+ expect(hasPlan(PLAN)).toBe(true);
8
+ });
9
+ it('detects a --- separator section', () => {
10
+ expect(hasPlan('Original text\n---\nAgent notes')).toBe(true);
11
+ });
12
+ it.each([null, undefined, '', 'Just a plain description'])('rejects %j', (description) => {
13
+ expect(hasPlan(description)).toBe(false);
14
+ });
15
+ });
16
+ describe('allTasksChecked', () => {
17
+ it('is true when every task is checked', () => {
18
+ expect(allTasksChecked(DONE_PLAN)).toBe(true);
19
+ });
20
+ it('is false while unchecked tasks remain', () => {
21
+ expect(allTasksChecked(PLAN)).toBe(false);
22
+ });
23
+ it.each([null, undefined, '', 'No checklist here'])('is false without a checklist (%j)', (description) => {
24
+ expect(allTasksChecked(description)).toBe(false);
25
+ });
26
+ });
27
+ describe('getWorkItemReminders', () => {
28
+ it('tells agents to pull pending items', () => {
29
+ expect(getWorkItemReminders('pending', PLAN)).toEqual([
30
+ expect.stringContaining('pull_work_item'),
31
+ ]);
32
+ });
33
+ it('tells agents to move new items to doing', () => {
34
+ expect(getWorkItemReminders('new', PLAN)).toEqual([
35
+ expect.stringContaining('set status to "doing"'),
36
+ ]);
37
+ });
38
+ it('tells agents to move doing items to review when complete', () => {
39
+ expect(getWorkItemReminders('doing', PLAN)).toEqual([
40
+ expect.stringContaining('set status to "review"'),
41
+ ]);
42
+ });
43
+ it('adds the no-plan reminder when the description has no plan', () => {
44
+ const reminders = getWorkItemReminders('new', 'Just a description');
45
+ expect(reminders).toHaveLength(2);
46
+ expect(reminders[1]).toContain('no plan');
47
+ });
48
+ it('stays quiet for statuses with no required action', () => {
49
+ expect(getWorkItemReminders('review', PLAN)).toEqual([]);
50
+ expect(getWorkItemReminders('completed', PLAN)).toEqual([]);
51
+ });
52
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolfpack-mcp",
3
- "version": "1.0.62",
3
+ "version": "1.0.64",
4
4
  "description": "MCP server for Wolfpack AI-enhanced software delivery tools",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",