import { join } from 'path'; import { getEntityDir } from '../paths.js'; import { getNextId } from '../counter.js'; import { readEntity, writeEntity } from '../files.js'; import { TaskSchema, type Task } from '../schema.js'; import { Index } from '../index.js'; export function createTask(cwd: string, options: Partial = {}): Task { const now = new Date().toISOString(); const task: Task = TaskSchema.parse({ id: getNextId(cwd, 'task'), title: options.title ?? 'Untitled', description: options.description ?? '', status: 'open', priority: options.priority ?? 'medium', role: options.role, assignedTo: options.assignedTo, createdAt: now, updatedAt: now, }); const filePath = join(getEntityDir(cwd, 'tasks'), `${task.id}.md`); writeEntity(filePath, task, `# ${task.title}\n\n${task.description}`); const index = new Index(cwd); index.upsert(toIndexEntry(task, filePath)); index.close(); return task; } export function listTasks(cwd: string, filters?: { status?: string; role?: string }): ReturnType { const index = new Index(cwd); const tasks = index.list('task', filters); index.close(); return tasks; } export function getTask(cwd: string, id: string): { task: Task; body: string; filePath: string } { const filePath = join(getEntityDir(cwd, 'tasks'), `${id}.md`); const { frontmatter, body } = readEntity(filePath); return { task: TaskSchema.parse(frontmatter), body, filePath }; } export function updateTask(cwd: string, id: string, patch: Partial): Task { const { task, body, filePath } = getTask(cwd, id); const updated: Task = TaskSchema.parse({ ...task, ...patch, updatedAt: new Date().toISOString() }); writeEntity(filePath, updated, body); const index = new Index(cwd); index.upsert(toIndexEntry(updated, filePath)); index.close(); return updated; } export function claimTask(cwd: string, id: string, agentName: string): Task { return updateTask(cwd, id, { status: 'in_progress', assignedTo: agentName }); } export function doneTask(cwd: string, id: string): Task { return updateTask(cwd, id, { status: 'done' }); } function toIndexEntry(task: Task, filePath: string) { return { id: task.id, type: 'task', title: task.title, content: `${task.description} ${task.tags.join(' ')}`, filePath, createdAt: task.createdAt, updatedAt: task.updatedAt, status: task.status, role: task.role, assignedTo: task.assignedTo, tags: JSON.stringify(task.tags), }; }