-
-
Notifications
You must be signed in to change notification settings - Fork 3
Closed
Labels
Description
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.tsAdd 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 passCommit
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"Reactions are currently unavailable