import { describe, expect, it, vi } from 'vitest'; import { runQueueCli, type QueueCliDependencies, type QueueRepository } from '../src/cli.js'; import type { Task } from '@mosaic/types'; function createRepositoryMock(): QueueRepository { return { create: vi.fn(() => Promise.resolve({ id: 'MQ-005', project: 'queue', mission: 'phase1', taskId: 'MQ-005', title: 'Build CLI', status: 'pending', priority: 'medium', dependencies: [], lane: 'any', retryCount: 0, createdAt: 1, updatedAt: 1, }), ), list: vi.fn(() => Promise.resolve([])), get: vi.fn(() => Promise.resolve(null)), claim: vi.fn(() => Promise.resolve({ id: 'MQ-005', project: 'queue', mission: 'phase1', taskId: 'MQ-005', title: 'Build CLI', status: 'claimed', priority: 'medium', dependencies: [], lane: 'any', claimedBy: 'agent-a', claimedAt: 2, claimTTL: 60, retryCount: 0, createdAt: 1, updatedAt: 2, }), ), release: vi.fn(() => Promise.resolve({ id: 'MQ-005', project: 'queue', mission: 'phase1', taskId: 'MQ-005', title: 'Build CLI', status: 'pending', priority: 'medium', dependencies: [], lane: 'any', retryCount: 0, createdAt: 1, updatedAt: 3, }), ), complete: vi.fn(() => Promise.resolve({ id: 'MQ-005', project: 'queue', mission: 'phase1', taskId: 'MQ-005', title: 'Build CLI', status: 'completed', priority: 'medium', dependencies: [], lane: 'any', completionSummary: 'done', retryCount: 0, createdAt: 1, updatedAt: 4, completedAt: 4, }), ), }; } function createDependencies( repository: QueueRepository, ): QueueCliDependencies & { outputs: string[]; errors: string[] } { const outputs: string[] = []; const errors: string[] = []; const close = vi.fn(() => Promise.resolve(undefined)); return { openSession: () => Promise.resolve({ repository, close, }), stdout: (line) => { outputs.push(line); }, stderr: (line) => { errors.push(line); }, outputs, errors, }; } describe('runQueueCli', () => { it('creates a task from command options', async () => { const repository = createRepositoryMock(); const dependencies = createDependencies(repository); const exitCode = await runQueueCli( [ 'node', 'mosaic', 'queue', 'create', 'queue', 'phase1', 'MQ-005', '--title', 'Build CLI', '--priority', 'high', '--lane', 'coding', '--dependency', 'MQ-002', 'MQ-003', ], dependencies, ); expect(exitCode).toBe(0); expect(repository.create).toHaveBeenCalledWith({ project: 'queue', mission: 'phase1', taskId: 'MQ-005', title: 'Build CLI', description: undefined, priority: 'high', dependencies: ['MQ-002', 'MQ-003'], lane: 'coding', }); }); it('lists tasks with filters', async () => { const repository = createRepositoryMock(); const dependencies = createDependencies(repository); const exitCode = await runQueueCli( [ 'node', 'mosaic', 'queue', 'list', '--project', 'queue', '--mission', 'phase1', '--status', 'pending', ], dependencies, ); expect(exitCode).toBe(0); expect(repository.list).toHaveBeenCalledWith({ project: 'queue', mission: 'phase1', status: 'pending', }); }); it('claims and completes tasks with typed options', async () => { const repository = createRepositoryMock(); const dependencies = createDependencies(repository); const claimExitCode = await runQueueCli( [ 'node', 'mosaic', 'queue', 'claim', 'MQ-005', '--agent', 'agent-a', '--ttl', '60', ], dependencies, ); const completeExitCode = await runQueueCli( [ 'node', 'mosaic', 'queue', 'complete', 'MQ-005', '--agent', 'agent-a', '--summary', 'done', ], dependencies, ); expect(claimExitCode).toBe(0); expect(completeExitCode).toBe(0); expect(repository.claim).toHaveBeenCalledWith('MQ-005', { agentId: 'agent-a', ttlSeconds: 60, }); expect(repository.complete).toHaveBeenCalledWith('MQ-005', { agentId: 'agent-a', summary: 'done', }); }); });