agenthub/src/core/services/taskService.ts
2026-06-25 12:18:49 +02:00

80 lines
2.5 KiB
TypeScript

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> = {}): 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<Index['list']> {
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>): 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),
};
}