- Mission CRUD: createMission, loadMission - TASKS.md parser/writer: parseTasksFile, writeTasksFile, updateTaskStatus - Task runner: runTask, resumeTask (spawns agent via child_process) - Status aggregation: getMissionStatus, getTaskStatus - CLI: coord init | run | resume | status - Depends on @mosaic/types and @mosaic/queue workspace:*
75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { parseTasksFile, writeTasksFile } from '../src/tasks-file.js';
|
|
import type { MissionTask } from '../src/types.js';
|
|
|
|
describe('parseTasksFile', () => {
|
|
it('normalizes legacy statuses from TASKS.md', () => {
|
|
const content = [
|
|
'# Tasks — Demo',
|
|
'',
|
|
'| id | status | milestone | description | pr | notes |',
|
|
'|----|--------|-----------|-------------|----|-------|',
|
|
'| T-1 | pending | phase-1 | First task | #10 | note a |',
|
|
'| T-2 | completed | phase-1 | Second task | #11 | note b |',
|
|
'| T-3 | in_progress | phase-2 | Third task | | |',
|
|
'| T-4 | failed | phase-2 | Fourth task | | |',
|
|
'',
|
|
'trailing text ignored',
|
|
].join('\n');
|
|
|
|
const tasks = parseTasksFile(content);
|
|
|
|
expect(tasks).toHaveLength(4);
|
|
expect(tasks.map((task) => task.status)).toEqual([
|
|
'not-started',
|
|
'done',
|
|
'in-progress',
|
|
'blocked',
|
|
]);
|
|
expect(tasks.map((task) => task.rawStatus)).toEqual([
|
|
'pending',
|
|
'completed',
|
|
'in_progress',
|
|
'failed',
|
|
]);
|
|
expect(tasks[0]?.line).toBe(5);
|
|
});
|
|
});
|
|
|
|
describe('writeTasksFile', () => {
|
|
it('round-trips parse/write output', () => {
|
|
const tasks: MissionTask[] = [
|
|
{
|
|
id: 'W3-001',
|
|
title: 'Implement parser',
|
|
status: 'not-started',
|
|
milestone: 'phase-1',
|
|
pr: '#20',
|
|
notes: 'pending',
|
|
dependencies: [],
|
|
},
|
|
{
|
|
id: 'W3-002',
|
|
title: 'Implement runner',
|
|
status: 'in-progress',
|
|
milestone: 'phase-2',
|
|
notes: 'active',
|
|
dependencies: [],
|
|
},
|
|
];
|
|
|
|
const content = writeTasksFile(tasks);
|
|
const reparsed = parseTasksFile(content);
|
|
|
|
expect(reparsed).toHaveLength(2);
|
|
expect(reparsed.map((task) => task.id)).toEqual(['W3-001', 'W3-002']);
|
|
expect(reparsed.map((task) => task.status)).toEqual([
|
|
'not-started',
|
|
'in-progress',
|
|
]);
|
|
expect(reparsed[0]?.title).toBe('Implement parser');
|
|
expect(reparsed[1]?.milestone).toBe('phase-2');
|
|
});
|
|
});
|