Skip to content

feat(mcp): implement taskmaestro dispatch strategy in AgentService #709

@JeremyDev87

Description

@JeremyDev87

Task 4 of 7 — TaskMaestro Specialist Strategy

Spec: docs/superpowers/specs/2026-03-19-taskmaestro-specialist-strategy-design.md
Depends on: Task 1 (types), Task 3 (tool input)
Blocks: Tasks 5, 6, 7


Goal

Implement the taskmaestro execution strategy branch in AgentService.dispatchAgents(). When executionStrategy === 'taskmaestro', return TaskmaestroDispatch with session name, pane count, and per-agent assignments instead of parallelAgents with dispatchParams.

Files to Modify

1. apps/mcp-server/src/agent/agent.service.ts

Find dispatchAgents() method:

grep -n "dispatchAgents\|async dispatchAgents" apps/mcp-server/src/agent/agent.service.ts

Add strategy branch — before the existing parallel agents logic, add:

if (input.executionStrategy === 'taskmaestro') {
  const specialistNames = input.specialists ?? [];
  const loadedAgents = await this.loadAgents(specialistNames, 'full');

  const assignments: TaskmaestroAssignment[] = loadedAgents.map(agent => ({
    name: agent.name,
    displayName: agent.displayName ?? agent.name,
    prompt: this.buildTaskmaestroPrompt(agent, input),
  }));

  return {
    primaryAgent: primaryResult,
    taskmaestro: {
      sessionName: `${(input.mode ?? 'eval').toLowerCase()}-specialists`,
      paneCount: assignments.length,
      assignments,
    },
    executionStrategy: 'taskmaestro',
    executionHint: this.buildTaskmaestroHint(assignments.length),
    failedAgents: failedResult,
  };
}

Add helper methods:

private buildTaskmaestroPrompt(agent: any, input: DispatchAgentsInput): string {
  const taskContext = input.taskDescription
    ? `\n\n**Task:** ${input.taskDescription}`
    : '';
  const fileContext = input.targetFiles?.length
    ? `\n\n**Target Files:**\n${input.targetFiles.map(f => '- ' + f).join('\n')}`
    : '';

  return `${agent.systemPrompt ?? agent.summary ?? ''}${taskContext}${fileContext}

**Output Format:**
- Severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
- File reference
- Finding description
- Recommendation

When done, provide a summary of all findings.`;
}

private buildTaskmaestroHint(paneCount: number): string {
  return `TaskMaestro execution:
1. /taskmaestro start --panes ${paneCount}
2. Wait for all panes to show Claude Code prompt
3. For each assignment: /taskmaestro assign <pane_index> "<prompt>"
4. /taskmaestro status — monitor progress
5. When all panes show idle: collect results
6. /taskmaestro stop all — cleanup`;
}

Add executionStrategy to the existing subagent return — in the existing return path (non-taskmaestro), add:

executionStrategy: 'subagent',

Import types at top:

import { TaskmaestroAssignment, TaskmaestroDispatch } from './agent.types';

2. apps/mcp-server/src/agent/agent.service.spec.ts

Add test suite:

describe('dispatchAgents with taskmaestro strategy', () => {
  it('should return taskmaestro field with assignments when strategy is taskmaestro', async () => {
    const result = await service.dispatchAgents({
      mode: 'EVAL',
      specialists: ['security-specialist', 'performance-specialist'],
      executionStrategy: 'taskmaestro',
    });

    expect(result.taskmaestro).toBeDefined();
    expect(result.taskmaestro!.paneCount).toBe(2);
    expect(result.taskmaestro!.assignments).toHaveLength(2);
    expect(result.taskmaestro!.sessionName).toBe('eval-specialists');
    expect(result.executionStrategy).toBe('taskmaestro');
  });

  it('should not include parallelAgents when strategy is taskmaestro', async () => {
    const result = await service.dispatchAgents({
      mode: 'EVAL',
      specialists: ['security-specialist'],
      executionStrategy: 'taskmaestro',
    });

    expect(result.parallelAgents).toBeUndefined();
    expect(result.taskmaestro).toBeDefined();
  });

  it('should include task description and target files in taskmaestro prompt', async () => {
    const result = await service.dispatchAgents({
      mode: 'EVAL',
      specialists: ['security-specialist'],
      executionStrategy: 'taskmaestro',
      taskDescription: 'Review auth flow',
      targetFiles: ['src/auth.ts', 'src/middleware.ts'],
    });

    const prompt = result.taskmaestro!.assignments[0].prompt;
    expect(prompt).toContain('Review auth flow');
    expect(prompt).toContain('src/auth.ts');
    expect(prompt).toContain('src/middleware.ts');
  });

  it('should include execution hint with correct pane count', async () => {
    const result = await service.dispatchAgents({
      mode: 'PLAN',
      specialists: ['architecture-specialist', 'test-strategy-specialist', 'integration-specialist'],
      executionStrategy: 'taskmaestro',
    });

    expect(result.executionHint).toContain('/taskmaestro start --panes 3');
    expect(result.executionHint).toContain('/taskmaestro assign');
  });

  it('should set sessionName based on mode', async () => {
    const planResult = await service.dispatchAgents({
      mode: 'PLAN', specialists: ['architecture-specialist'], executionStrategy: 'taskmaestro',
    });
    expect(planResult.taskmaestro!.sessionName).toBe('plan-specialists');

    const actResult = await service.dispatchAgents({
      mode: 'ACT', specialists: ['code-quality-specialist'], executionStrategy: 'taskmaestro',
    });
    expect(actResult.taskmaestro!.sessionName).toBe('act-specialists');
  });

  it('should still return subagent format when strategy is subagent', async () => {
    const result = await service.dispatchAgents({
      mode: 'EVAL',
      specialists: ['security-specialist'],
      executionStrategy: 'subagent',
      includeParallel: true,
    });

    expect(result.parallelAgents).toBeDefined();
    expect(result.taskmaestro).toBeUndefined();
    expect(result.executionStrategy).toBe('subagent');
  });
});

Verification

cd /Users/pjw/workspace/codingbuddy
yarn workspace codingbuddy test -- --grep "taskmaestro strategy" 2>&1 | tail -15
# Expected: 6 tests pass

yarn workspace codingbuddy test 2>&1 | tail -5
# Expected: All existing tests still pass

Commit

git add apps/mcp-server/src/agent/agent.service.ts apps/mcp-server/src/agent/agent.service.spec.ts
git commit -m "feat(mcp): implement taskmaestro dispatch strategy in AgentService"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions