--- phase: 05-task-dispatch plan: 04 type: execute wave: 2 depends_on: ["05-01", "05-03"] files_modified: [src/dispatch/manager.ts, src/dispatch/manager.test.ts, src/dispatch/index.ts] autonomous: true --- Implement DispatchManager adapter with dependency checking and queue management. Purpose: TASK-04 requires dependency-ordered dispatch, TASK-05 requires work queue. Implement the DispatchManager adapter that checks task dependencies before dispatch and manages the work queue. Output: DispatchManager adapter with dependency algorithm, queue management, and tests. @~/.claude/get-shit-done/workflows/execute-plan.md @~/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/05-task-dispatch/05-01-SUMMARY.md @.planning/phases/05-task-dispatch/05-03-SUMMARY.md @src/dispatch/types.ts @src/db/schema.ts @src/db/repositories/task-repository.ts @src/agent/types.ts @src/events/types.ts Task 1: Implement dependency checking algorithm src/dispatch/manager.ts Create DefaultDispatchManager class implementing DispatchManager interface. Constructor dependencies (inject via constructor): - taskRepository: TaskRepository - messageRepository: MessageRepository (from 05-01) - agentManager: AgentManager - eventBus: EventBus Implement core dependency algorithm: 1. queue(taskId): - Fetch task and its dependencies from task_dependencies table - Add to internal queue (use Map) - Emit TaskQueuedEvent 2. getNextDispatchable(): - Get all queued tasks - For each, check if ALL dependencies have status='completed' - Filter to only ready tasks (all deps complete) - Sort by priority (high > medium > low), then by queuedAt (oldest first) - Return first or null 3. completeTask(taskId): - Update task status to 'completed' via taskRepository - Remove from queue - Emit TaskCompletedEvent - Note: dependent tasks automatically become ready on next getNextDispatchable call 4. blockTask(taskId, reason): - Update task status to 'blocked' via taskRepository - Emit TaskBlockedEvent Use simple in-memory queue (Map). Production could use persistent queue but in-memory is fine for v1. npm run build passes Dependency checking algorithm implemented Task 2: Implement dispatchNext and queue state src/dispatch/manager.ts Complete DispatchManager implementation: 1. dispatchNext(): - Call getNextDispatchable() to get next task - If null, return { success: false, taskId: '', reason: 'No dispatchable tasks' } - Find available agent (status='idle') via agentManager.list() - If no available agent, return { success: false, taskId, reason: 'No available agents' } - Get task details from taskRepository - Spawn agent with task: agentManager.spawn({ name: generateAgentName(), taskId, prompt: task.description || task.name }) - Update task status to 'in_progress' - Emit TaskDispatchedEvent - Return { success: true, taskId, agentId } 2. getQueueState(): - Return { queued: [...allQueuedTasks], ready: [...readyTasks], blocked: [...blockedTasks] } - Uses internal queue state Helper: generateAgentName(): - Generate unique name for agent (e.g., 'agent-${nanoid(6)}' or use Vancouver neighborhood names: 'gastown', 'yaletown', 'kitsilano', etc.) - For v1: simple 'agent-${taskId.slice(0,6)}' is fine Handle edge cases: - Task not found: throw error - Circular dependencies: not checked in v1 (assume valid DAG) npm run build passes dispatchNext and getQueueState implemented Task 3: Add tests and wire up exports src/dispatch/manager.test.ts, src/dispatch/index.ts Create manager.test.ts with tests: 1. Setup: - Create in-memory database with createTestDatabase helper - Create mock/real repositories and EventBus - Create test tasks with dependencies 2. Test cases: - queue adds task to queue and emits event - getNextDispatchable returns null when queue empty - getNextDispatchable returns task when dependencies complete - getNextDispatchable returns null when dependencies incomplete - getNextDispatchable respects priority ordering - completeTask updates status and emits event - blockTask updates status and emits event - dispatchNext returns failure when no tasks ready - dispatchNext returns failure when no agents available - getQueueState returns correct state 3. Test dependency scenario: - Task A (no deps) - Task B (depends on A) - Task C (depends on A) - Queue all three - Only A should be dispatchable - Complete A - B and C should become dispatchable Update index.ts to export DefaultDispatchManager class. npm test -- src/dispatch/manager.test.ts passes Tests pass, DispatchManager exported Before declaring plan complete: - [ ] npm run build succeeds - [ ] npm test passes all tests - [ ] Dependency ordering works correctly - [ ] Queue state accurately reflects task readiness - DefaultDispatchManager implements DispatchManager interface - Dependency checking prevents premature dispatch - Priority ordering respected - All dispatch events emitted correctly - Tests cover core scenarios After completion, create `.planning/phases/05-task-dispatch/05-04-SUMMARY.md`