import { createRouter } from '../../create-router'; import { listTasks, getTaskByDirName, createTask, deleteTask, readCategoryOrder } from './task-files'; type TriggerConfig = { type: 'file'; extensions: string[] } | { type: 'directory' }; export const tasksRouter = createRouter(); tasksRouter.get('/', async (ctx) => { const summaries = await listTasks(); const tasks = summaries.map((row) => ({ dirName: row.dirName, name: row.name, description: row.description, category: row.category, triggers: (row.trigger as TriggerConfig[]) ?? [], mode: row.mode ?? 'agentic', })); return ctx.json(tasks); }); // Must be declared before '/:name', which would otherwise match "categories". tasksRouter.get('/categories', async (ctx) => { return ctx.json(await readCategoryOrder()); }); tasksRouter.get('/:name', async (ctx) => { const name = ctx.req.param('name'); const task = await getTaskByDirName(name); if (!task) return ctx.text('Not found', 404); return ctx.json({ dirName: task.dirName, name: task.name, description: task.description, category: task.category, mode: task.mode, inline: task.inline, language: task.language, body: task.body, implementation: task.implementation, inputs: task.inputs, args: task.args, trigger: task.trigger, config: task.config, version: task.version, filePath: task.filePath, }); }); tasksRouter.post('/', async (ctx) => { const body = await ctx.req.json<{ name: string; description?: string; mode?: string; language?: string }>(); if (!body.name?.trim()) return ctx.text('Name is required', 400); try { const task = await createTask({ name: body.name, description: body.description ?? null, mode: body.mode ?? 'agentic', language: body.language ?? null, }); return ctx.json(task); } catch (err) { const message = err instanceof Error ? err.message : 'Failed to create task'; return ctx.text(message, message === 'Task already exists' ? 409 : 400); } }); tasksRouter.delete('/:name', async (ctx) => { const name = ctx.req.param('name'); const task = await getTaskByDirName(name); if (!task) return ctx.text('Not found', 404); await deleteTask(task.dirName); return ctx.json({ ok: true }); });