import { z } from "zod";
import { log } from "../core/logger.js";
import { createTaskRecord, loadTasks, saveTasks } from "../core/tasks-store.js";
const TasksParams = z.object({
    action: z
        .enum(["add", "list", "done", "remove"])
        .describe("Action: add a task, list tasks, mark done, or remove"),
    title: z
        .string()
        .optional()
        .describe("Short task title for display (max ~10 words, required for add)"),
    prompt: z
        .string()
        .optional()
        .describe("The standalone prompt sent to an agent with no context (required for add). " +
        "Concise, actionable instruction with file paths and what to change."),
    id: z.string().optional().describe("Task ID (required for done/remove — use list to find IDs)"),
});
export function createTasksTool(cwd) {
    let pending = Promise.resolve();
    function enqueue(fn) {
        const result = pending.then(fn);
        pending = result.then(() => { }, () => { });
        return result;
    }
    return {
        name: "tasks",
        description: "Manage the project task list. Each task has a short title (shown in " +
            "the task pane) and a prompt (sent as a standalone instruction to an " +
            "agent with no context). Write prompts as concise, actionable directives " +
            "with specific file paths — the agent must complete it from the prompt alone. " +
            "When adding multiple tasks, order them by dependency — foundational work " +
            "first, then core logic, integration, UI, and tests. " +
            "Do not use this tool proactively — only manage the task list when the user explicitly requests it.",
        parameters: TasksParams,
        executionMode: "sequential",
        execute({ action, title, prompt, id }) {
            return enqueue(async () => {
                switch (action) {
                    case "add": {
                        if (!title)
                            return "Error: title is required for add action.";
                        if (!prompt)
                            return "Error: prompt is required for add action.";
                        const tasks = await loadTasks(cwd);
                        const task = createTaskRecord(title, prompt);
                        tasks.push(task);
                        await saveTasks(cwd, tasks);
                        log("INFO", "tasks", `Task added: ${title}`, { id: task.id });
                        return `Task added: "${title}" (id: ${task.id.slice(0, 8)})`;
                    }
                    case "list": {
                        const tasks = await loadTasks(cwd);
                        if (tasks.length === 0)
                            return "No tasks.";
                        const lines = tasks.map((task) => {
                            const check = task.status === "done" ? "✓" : task.status === "in-progress" ? "~" : " ";
                            return `[${check}] ${task.title}  (id: ${task.id.slice(0, 8)}, ${task.status})`;
                        });
                        log("INFO", "tasks", `Listed ${tasks.length} tasks`);
                        return lines.join("\n");
                    }
                    case "done": {
                        if (!id)
                            return "Error: id is required for done action.";
                        const tasks = await loadTasks(cwd);
                        const task = tasks.find((candidate) => candidate.id === id || candidate.id.startsWith(id));
                        if (!task)
                            return `Error: no task found matching id "${id}".`;
                        task.status = "done";
                        await saveTasks(cwd, tasks);
                        log("INFO", "tasks", `Task done: ${task.title}`, { id: task.id });
                        return `Marked done: "${task.title}"`;
                    }
                    case "remove": {
                        if (!id)
                            return "Error: id is required for remove action.";
                        const tasks = await loadTasks(cwd);
                        const idx = tasks.findIndex((candidate) => candidate.id === id || candidate.id.startsWith(id));
                        if (idx === -1)
                            return `Error: no task found matching id "${id}".`;
                        const [removed] = tasks.splice(idx, 1);
                        if (!removed)
                            return `Error: no task found matching id "${id}".`;
                        await saveTasks(cwd, tasks);
                        log("INFO", "tasks", `Task removed: ${removed.title}`, { id: removed.id });
                        return `Removed: "${removed.title}"`;
                    }
                }
            });
        },
    };
}
//# sourceMappingURL=tasks.js.map