From d90978d16beb7279dc46419b5b0e1e8cb185582d Mon Sep 17 00:00:00 2001 From: JeremyDev87 Date: Thu, 19 Mar 2026 17:20:41 +0900 Subject: [PATCH 1/6] feat(mcp): add TaskMaestro dispatch types and availableStrategies - Add TaskmaestroAssignment and TaskmaestroDispatch interfaces - Extend DispatchAgentsInput with executionStrategy field - Extend DispatchResult with taskmaestro and executionStrategy fields - Extend ParseModeResult with availableStrategies and taskmaestroInstallHint - Add type tests for new interfaces Closes #706 --- apps/mcp-server/src/agent/agent.types.spec.ts | 84 +++++++++++++++++++ apps/mcp-server/src/agent/agent.types.ts | 24 ++++++ apps/mcp-server/src/keyword/keyword.types.ts | 4 + 3 files changed, 112 insertions(+) create mode 100644 apps/mcp-server/src/agent/agent.types.spec.ts diff --git a/apps/mcp-server/src/agent/agent.types.spec.ts b/apps/mcp-server/src/agent/agent.types.spec.ts new file mode 100644 index 00000000..0341d3b9 --- /dev/null +++ b/apps/mcp-server/src/agent/agent.types.spec.ts @@ -0,0 +1,84 @@ +import { describe, it, expect } from 'vitest'; +import type { + TaskmaestroAssignment, + TaskmaestroDispatch, + DispatchAgentsInput, + DispatchResult, +} from './agent.types'; + +describe('agent.types - TaskMaestro types', () => { + describe('TaskmaestroAssignment', () => { + it('accepts object with name, displayName, prompt', () => { + const assignment: TaskmaestroAssignment = { + name: 'frontend-dev', + displayName: 'Frontend Developer', + prompt: 'Implement the UI component', + }; + expect(assignment.name).toBe('frontend-dev'); + expect(assignment.displayName).toBe('Frontend Developer'); + expect(assignment.prompt).toBe('Implement the UI component'); + }); + }); + + describe('TaskmaestroDispatch', () => { + it('accepts object with sessionName, paneCount, assignments', () => { + const dispatch: TaskmaestroDispatch = { + sessionName: 'workspace-1', + paneCount: 3, + assignments: [ + { name: 'dev-1', displayName: 'Dev 1', prompt: 'Task 1' }, + ], + }; + expect(dispatch.sessionName).toBe('workspace-1'); + expect(dispatch.paneCount).toBe(3); + expect(dispatch.assignments).toHaveLength(1); + }); + }); + + describe('DispatchAgentsInput - executionStrategy', () => { + it('accepts executionStrategy: subagent', () => { + const input: DispatchAgentsInput = { + mode: 'PLAN', + executionStrategy: 'subagent', + }; + expect(input.executionStrategy).toBe('subagent'); + }); + + it('accepts executionStrategy: taskmaestro', () => { + const input: DispatchAgentsInput = { + mode: 'ACT', + executionStrategy: 'taskmaestro', + }; + expect(input.executionStrategy).toBe('taskmaestro'); + }); + + it('executionStrategy is optional', () => { + const input: DispatchAgentsInput = { mode: 'PLAN' }; + expect(input.executionStrategy).toBeUndefined(); + }); + }); + + describe('DispatchResult - taskmaestro fields', () => { + it('accepts optional taskmaestro dispatch data', () => { + const result: DispatchResult = { + executionHint: 'Use taskmaestro for parallel execution', + taskmaestro: { + sessionName: 'ws-1', + paneCount: 2, + assignments: [], + }, + executionStrategy: 'taskmaestro', + }; + expect(result.taskmaestro?.sessionName).toBe('ws-1'); + expect(result.executionStrategy).toBe('taskmaestro'); + }); + + it('taskmaestro and executionStrategy are optional', () => { + const result: DispatchResult = { + executionHint: 'Use subagent', + }; + expect(result.taskmaestro).toBeUndefined(); + expect(result.executionStrategy).toBeUndefined(); + }); + }); +}); diff --git a/apps/mcp-server/src/agent/agent.types.ts b/apps/mcp-server/src/agent/agent.types.ts index 58c943ff..c097bb1c 100644 --- a/apps/mcp-server/src/agent/agent.types.ts +++ b/apps/mcp-server/src/agent/agent.types.ts @@ -73,6 +73,24 @@ export interface DispatchedAgent { dispatchParams: DispatchParams; } +/** + * A single TaskMaestro pane assignment with agent name and prompt + */ +export interface TaskmaestroAssignment { + name: string; + displayName: string; + prompt: string; +} + +/** + * TaskMaestro dispatch configuration for parallel tmux pane execution + */ +export interface TaskmaestroDispatch { + sessionName: string; + paneCount: number; + assignments: TaskmaestroAssignment[]; +} + /** * Result of dispatching agents for execution */ @@ -82,6 +100,10 @@ export interface DispatchResult { executionHint: string; /** Agents that failed to load */ failedAgents?: FailedAgent[]; + /** TaskMaestro dispatch data when executionStrategy is 'taskmaestro' */ + taskmaestro?: TaskmaestroDispatch; + /** Execution strategy used for this dispatch */ + executionStrategy?: string; } /** @@ -94,6 +116,8 @@ export interface DispatchAgentsInput { specialists?: string[]; includeParallel?: boolean; primaryAgent?: string; + /** Execution strategy: 'subagent' (default) or 'taskmaestro' */ + executionStrategy?: 'subagent' | 'taskmaestro'; } /** diff --git a/apps/mcp-server/src/keyword/keyword.types.ts b/apps/mcp-server/src/keyword/keyword.types.ts index c2e9eda8..fd9d7184 100644 --- a/apps/mcp-server/src/keyword/keyword.types.ts +++ b/apps/mcp-server/src/keyword/keyword.types.ts @@ -440,6 +440,10 @@ export interface ParseModeResult { * without needing to call dispatch_agents or prepare_parallel_agents. */ dispatchReady?: DispatchReady; + /** @apiProperty External API - do not rename. Available execution strategies (e.g. ['subagent', 'taskmaestro']) */ + availableStrategies?: string[]; + /** @apiProperty External API - do not rename. Hint for installing TaskMaestro when not available */ + taskmaestroInstallHint?: string; } /** From 51ae34e3328242501ca328c10470349ac922941e Mon Sep 17 00:00:00 2001 From: JeremyDev87 Date: Thu, 19 Mar 2026 18:48:58 +0900 Subject: [PATCH 2/6] feat(mcp): detect taskmaestro installation and populate availableStrategies - Add taskmaestro-detector.ts utility with isTaskmaestroAvailable() - Wire detection into buildParseModeResult() as step 10 - Populate availableStrategies and taskmaestroInstallHint in ParseModeResult - Add 2 tests for skill present/absent scenarios Closes #707 --- .../src/keyword/keyword.service.spec.ts | 27 +++++++++++++++++++ .../mcp-server/src/keyword/keyword.service.ts | 9 +++++++ .../src/keyword/taskmaestro-detector.ts | 16 +++++++++++ 3 files changed, 52 insertions(+) create mode 100644 apps/mcp-server/src/keyword/taskmaestro-detector.ts diff --git a/apps/mcp-server/src/keyword/keyword.service.spec.ts b/apps/mcp-server/src/keyword/keyword.service.spec.ts index 76c97741..c05ccd99 100644 --- a/apps/mcp-server/src/keyword/keyword.service.spec.ts +++ b/apps/mcp-server/src/keyword/keyword.service.spec.ts @@ -2677,4 +2677,31 @@ ${'Even more content.\n'.repeat(150)}`; expect(result.rules[0].content).toContain('## Section'); }); }); + + describe('taskmaestro detection', () => { + it('should include taskmaestro in availableStrategies when skill is available', async () => { + const detector = await import('./taskmaestro-detector'); + const spy = vi.spyOn(detector, 'isTaskmaestroAvailable').mockReturnValue(true); + + const result = await service.parseMode('PLAN test task', {}); + + expect(result.availableStrategies).toContain('subagent'); + expect(result.availableStrategies).toContain('taskmaestro'); + expect(result.taskmaestroInstallHint).toBeUndefined(); + + spy.mockRestore(); + }); + + it('should return only subagent with installHint when taskmaestro not installed', async () => { + const detector = await import('./taskmaestro-detector'); + const spy = vi.spyOn(detector, 'isTaskmaestroAvailable').mockReturnValue(false); + + const result = await service.parseMode('PLAN test task', {}); + + expect(result.availableStrategies).toEqual(['subagent']); + expect(result.taskmaestroInstallHint).toContain('TaskMaestro skill not found'); + + spy.mockRestore(); + }); + }); }); diff --git a/apps/mcp-server/src/keyword/keyword.service.ts b/apps/mcp-server/src/keyword/keyword.service.ts index 04e94154..081ab6e1 100644 --- a/apps/mcp-server/src/keyword/keyword.service.ts +++ b/apps/mcp-server/src/keyword/keyword.service.ts @@ -32,6 +32,7 @@ import { truncateSkillContent } from '../skill/skill-content.utils'; import { createAgentSummary } from '../agent/agent-summary.utils'; import { truncateRuleContent } from '../rules/rules-content.utils'; import { getDefaultModeConfig } from '../shared/keyword-core'; +import { isTaskmaestroAvailable } from './taskmaestro-detector'; import { type ClientType } from '../shared/client-type'; /** @@ -496,6 +497,14 @@ export class KeywordService { // 9. Auto-include primary agent system prompt (for MCP mode to force AI execution) await this.addIncludedAgentToResult(result, mode, options); + // 10. Add available execution strategies (subagent, taskmaestro) + const taskmaestroInstalled = isTaskmaestroAvailable(); + result.availableStrategies = taskmaestroInstalled ? ['subagent', 'taskmaestro'] : ['subagent']; + if (!taskmaestroInstalled) { + result.taskmaestroInstallHint = + 'TaskMaestro skill not found at ~/.claude/skills/taskmaestro/SKILL.md. To enable tmux-based parallel specialist execution, install the taskmaestro skill.'; + } + return result; } diff --git a/apps/mcp-server/src/keyword/taskmaestro-detector.ts b/apps/mcp-server/src/keyword/taskmaestro-detector.ts new file mode 100644 index 00000000..4d345c44 --- /dev/null +++ b/apps/mcp-server/src/keyword/taskmaestro-detector.ts @@ -0,0 +1,16 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; + +/** + * Check if the TaskMaestro skill is installed at the expected path. + * @returns true if ~/.claude/skills/taskmaestro/SKILL.md exists + */ +export function isTaskmaestroAvailable(): boolean { + const skillPath = path.join(os.homedir(), '.claude', 'skills', 'taskmaestro', 'SKILL.md'); + try { + return fs.existsSync(skillPath); + } catch { + return false; + } +} From 79b7283d134900a0b8d5a2c14099a26427874f59 Mon Sep 17 00:00:00 2001 From: JeremyDev87 Date: Thu, 19 Mar 2026 18:52:46 +0900 Subject: [PATCH 3/6] feat(mcp): add executionStrategy parameter to dispatch_agents tool - Add executionStrategy enum ('subagent' | 'taskmaestro') to inputSchema - Extract and default to 'subagent' in handleDispatchAgents handler - Add 3 tests for subagent, taskmaestro, and default scenarios Closes #708 --- .../src/mcp/handlers/agent.handler.spec.ts | 34 +++++++++++++++++++ .../src/mcp/handlers/agent.handler.ts | 9 +++++ 2 files changed, 43 insertions(+) diff --git a/apps/mcp-server/src/mcp/handlers/agent.handler.spec.ts b/apps/mcp-server/src/mcp/handlers/agent.handler.spec.ts index 29159b63..c75acc77 100644 --- a/apps/mcp-server/src/mcp/handlers/agent.handler.spec.ts +++ b/apps/mcp-server/src/mcp/handlers/agent.handler.spec.ts @@ -433,6 +433,40 @@ describe('AgentHandler', () => { text: expect.stringContaining('Dispatch failed'), }); }); + + describe('executionStrategy parameter', () => { + it('should pass executionStrategy "subagent" to service', async () => { + await handler.handle('dispatch_agents', { + mode: 'EVAL', + specialists: ['security-specialist'], + executionStrategy: 'subagent', + }); + expect(mockAgentService.dispatchAgents).toHaveBeenCalledWith( + expect.objectContaining({ executionStrategy: 'subagent' }), + ); + }); + + it('should pass executionStrategy "taskmaestro" to service', async () => { + await handler.handle('dispatch_agents', { + mode: 'EVAL', + specialists: ['security-specialist'], + executionStrategy: 'taskmaestro', + }); + expect(mockAgentService.dispatchAgents).toHaveBeenCalledWith( + expect.objectContaining({ executionStrategy: 'taskmaestro' }), + ); + }); + + it('should default executionStrategy to "subagent" when not specified', async () => { + await handler.handle('dispatch_agents', { + mode: 'EVAL', + specialists: ['security-specialist'], + }); + expect(mockAgentService.dispatchAgents).toHaveBeenCalledWith( + expect.objectContaining({ executionStrategy: 'subagent' }), + ); + }); + }); }); }); diff --git a/apps/mcp-server/src/mcp/handlers/agent.handler.ts b/apps/mcp-server/src/mcp/handlers/agent.handler.ts index 6062419e..a65e71b8 100644 --- a/apps/mcp-server/src/mcp/handlers/agent.handler.ts +++ b/apps/mcp-server/src/mcp/handlers/agent.handler.ts @@ -158,6 +158,12 @@ export class AgentHandler extends AbstractHandler { type: 'boolean', description: 'Whether to include parallel specialist agents (default: false)', }, + executionStrategy: { + type: 'string', + enum: ['subagent', 'taskmaestro'], + description: + 'Execution strategy for specialist agents. "subagent" (default) uses Claude Code Agent tool with run_in_background. "taskmaestro" returns tmux pane assignments for /taskmaestro skill.', + }, }, required: ['mode'], }, @@ -182,6 +188,8 @@ export class AgentHandler extends AbstractHandler { const targetFiles = extractStringArray(args, 'targetFiles'); const taskDescription = extractOptionalString(args, 'taskDescription'); const includeParallel = args?.includeParallel === true; + const executionStrategy = + (args?.executionStrategy as 'subagent' | 'taskmaestro' | undefined) ?? 'subagent'; try { const result = await this.agentService.dispatchAgents({ @@ -191,6 +199,7 @@ export class AgentHandler extends AbstractHandler { targetFiles, taskDescription, includeParallel, + executionStrategy, }); return createJsonResponse(result); } catch (error) { From c650799c4bfd7abdd8cb2855f6cea59c76062f56 Mon Sep 17 00:00:00 2001 From: JeremyDev87 Date: Thu, 19 Mar 2026 18:59:29 +0900 Subject: [PATCH 4/6] feat(mcp): implement taskmaestro dispatch strategy in AgentService - Add taskmaestro branch in dispatchAgents() for executionStrategy === 'taskmaestro' - Build per-agent prompts with task description and target files context - Return TaskmaestroDispatch with sessionName, paneCount, and assignments - Add buildTaskmaestroPrompt and buildTaskmaestroHint helper methods - Set executionStrategy: 'subagent' on existing return path - Add 6 tests covering all taskmaestro dispatch scenarios Closes #709 --- .../src/agent/agent.service.spec.ts | 103 ++++++++++++++++++ apps/mcp-server/src/agent/agent.service.ts | 55 +++++++++- 2 files changed, 157 insertions(+), 1 deletion(-) diff --git a/apps/mcp-server/src/agent/agent.service.spec.ts b/apps/mcp-server/src/agent/agent.service.spec.ts index 6e49ed83..180a6299 100644 --- a/apps/mcp-server/src/agent/agent.service.spec.ts +++ b/apps/mcp-server/src/agent/agent.service.spec.ts @@ -578,4 +578,107 @@ describe('AgentService', () => { expect(result.parallelAgents).toHaveLength(1); }); }); + + describe('dispatchAgents with taskmaestro strategy', () => { + it('should return taskmaestro field with assignments when strategy is taskmaestro', async () => { + vi.mocked(mockRulesService.getAgent!) + .mockResolvedValueOnce(mockSecurityAgent) + .mockResolvedValueOnce(mockPerformanceAgent); + + 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 () => { + vi.mocked(mockRulesService.getAgent!).mockResolvedValueOnce(mockSecurityAgent); + + 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 () => { + vi.mocked(mockRulesService.getAgent!).mockResolvedValueOnce(mockSecurityAgent); + + 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 () => { + vi.mocked(mockRulesService.getAgent!) + .mockResolvedValueOnce(mockSecurityAgent) + .mockResolvedValueOnce(mockAccessibilityAgent) + .mockResolvedValueOnce(mockPerformanceAgent); + + 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 () => { + vi.mocked(mockRulesService.getAgent!).mockResolvedValueOnce(mockSecurityAgent); + const planResult = await service.dispatchAgents({ + mode: 'PLAN', + specialists: ['architecture-specialist'], + executionStrategy: 'taskmaestro', + }); + expect(planResult.taskmaestro!.sessionName).toBe('plan-specialists'); + + vi.mocked(mockRulesService.getAgent!).mockResolvedValueOnce(mockSecurityAgent); + 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 () => { + vi.mocked(mockRulesService.getAgent!).mockResolvedValueOnce(mockSecurityAgent); + + 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'); + }); + }); }); diff --git a/apps/mcp-server/src/agent/agent.service.ts b/apps/mcp-server/src/agent/agent.service.ts index f9690dbe..0a3f7e33 100644 --- a/apps/mcp-server/src/agent/agent.service.ts +++ b/apps/mcp-server/src/agent/agent.service.ts @@ -10,6 +10,7 @@ import type { DispatchAgentsInput, DispatchResult, DispatchedAgent, + TaskmaestroAssignment, } from './agent.types'; import { FILE_PATTERN_SPECIALISTS } from './agent.types'; import { @@ -222,7 +223,31 @@ export class AgentService { } } - // Dispatch parallel agents + // Dispatch taskmaestro strategy + if (input.executionStrategy === 'taskmaestro' && input.specialists?.length) { + const uniqueSpecialists = Array.from(new Set(input.specialists)); + const { agents, failedAgents } = await this.loadAgents(uniqueSpecialists, context, true); + + const assignments: TaskmaestroAssignment[] = agents.map(agent => ({ + name: agent.id, + displayName: agent.displayName, + prompt: this.buildTaskmaestroPrompt(agent, input), + })); + + return { + primaryAgent: result.primaryAgent, + taskmaestro: { + sessionName: `${(input.mode ?? 'eval').toLowerCase()}-specialists`, + paneCount: assignments.length, + assignments, + }, + executionStrategy: 'taskmaestro', + executionHint: this.buildTaskmaestroHint(assignments.length), + failedAgents: failedAgents.length > 0 ? failedAgents : result.failedAgents, + }; + } + + // Dispatch parallel agents (subagent strategy) if (input.includeParallel && input.specialists?.length) { const uniqueSpecialists = Array.from(new Set(input.specialists)); const { agents, failedAgents } = await this.loadAgents( @@ -251,6 +276,34 @@ export class AgentService { } } + result.executionStrategy = 'subagent'; return result; } + + private buildTaskmaestroPrompt(agent: PreparedAgent, 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.taskPrompt || 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 "" +4. /taskmaestro status — monitor progress +5. When all panes show idle: collect results +6. /taskmaestro stop all — cleanup`; + } } From 47e5797bf72dd2d3d75cb118bdcae90b0fe4a842 Mon Sep 17 00:00:00 2001 From: JeremyDev87 Date: Thu, 19 Mar 2026 19:02:51 +0900 Subject: [PATCH 5/6] feat(mcp): wire availableStrategies into parse_mode tool response - Verify availableStrategies is included in parse_mode response via ...result spread - Add 2 tests: availableStrategies array and taskmaestroInstallHint passthrough Closes #710 --- .../src/mcp/handlers/mode.handler.spec.ts | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/apps/mcp-server/src/mcp/handlers/mode.handler.spec.ts b/apps/mcp-server/src/mcp/handlers/mode.handler.spec.ts index 5123b759..5d211741 100644 --- a/apps/mcp-server/src/mcp/handlers/mode.handler.spec.ts +++ b/apps/mcp-server/src/mcp/handlers/mode.handler.spec.ts @@ -810,4 +810,36 @@ describe('ModeHandler', () => { expect(result?.isError).toBeFalsy(); }); }); + + describe('parse_mode availableStrategies', () => { + it('should include availableStrategies in parse_mode response', async () => { + mockKeywordService.parseMode = vi.fn().mockResolvedValue({ + ...mockParseModeResult, + availableStrategies: ['subagent', 'taskmaestro'], + }); + + const result = await handler.handle('parse_mode', { prompt: 'PLAN test task' }); + + expect(result?.isError).toBeFalsy(); + const parsed = JSON.parse(result!.content[0].text as string); + expect(parsed.availableStrategies).toBeDefined(); + expect(parsed.availableStrategies).toContain('subagent'); + expect(parsed.availableStrategies).toContain('taskmaestro'); + }); + + it('should include taskmaestroInstallHint when present', async () => { + mockKeywordService.parseMode = vi.fn().mockResolvedValue({ + ...mockParseModeResult, + availableStrategies: ['subagent'], + taskmaestroInstallHint: 'TaskMaestro skill not found', + }); + + const result = await handler.handle('parse_mode', { prompt: 'PLAN test task' }); + + expect(result?.isError).toBeFalsy(); + const parsed = JSON.parse(result!.content[0].text as string); + expect(parsed.availableStrategies).toEqual(['subagent']); + expect(parsed.taskmaestroInstallHint).toContain('TaskMaestro skill not found'); + }); + }); }); From 9d1bf2222701ad8a29885f813beaec7f342c61f5 Mon Sep 17 00:00:00 2001 From: JeremyDev87 Date: Fri, 20 Mar 2026 16:58:28 +0900 Subject: [PATCH 6/6] style(mcp): fix prettier formatting in agent.types.spec.ts --- apps/mcp-server/src/agent/agent.types.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/mcp-server/src/agent/agent.types.spec.ts b/apps/mcp-server/src/agent/agent.types.spec.ts index 0341d3b9..72a6bcd0 100644 --- a/apps/mcp-server/src/agent/agent.types.spec.ts +++ b/apps/mcp-server/src/agent/agent.types.spec.ts @@ -25,9 +25,7 @@ describe('agent.types - TaskMaestro types', () => { const dispatch: TaskmaestroDispatch = { sessionName: 'workspace-1', paneCount: 3, - assignments: [ - { name: 'dev-1', displayName: 'Dev 1', prompt: 'Task 1' }, - ], + assignments: [{ name: 'dev-1', displayName: 'Dev 1', prompt: 'Task 1' }], }; expect(dispatch.sessionName).toBe('workspace-1'); expect(dispatch.paneCount).toBe(3);