---
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