import { Type } from "@sinclair/typebox";
//#region src/agent/tools/todo-tool.ts
const VALID_STATUSES = new Set([
	"pending",
	"in_progress",
	"completed",
	"cancelled"
]);
const TodoItemSchema = Type.Object({
	id: Type.String({ description: "Unique identifier for the todo item" }),
	content: Type.String({ description: "Task description" }),
	status: Type.Union([
		Type.Literal("pending"),
		Type.Literal("in_progress"),
		Type.Literal("completed"),
		Type.Literal("cancelled")
	], { description: "Current status of the task" })
});
const TodoSchema = Type.Object({
	todos: Type.Optional(Type.Array(TodoItemSchema, { description: "Array of todo items to write. Omit to read current list." })),
	merge: Type.Optional(Type.Boolean({
		description: "When true, update existing items by id and append new ones. When false (default), replace the entire list.",
		default: false
	}))
});
var TodoStore = class {
	items = [];
	write(todos, merge) {
		if (!merge) {
			this.items = todos.map((t) => this.validate(t));
			return this.read();
		}
		const existing = new Map(this.items.map((item) => [item.id, item]));
		for (const todo of todos) {
			const itemId = String(todo.id ?? "").trim();
			if (!itemId) continue;
			if (existing.has(itemId)) {
				const current = existing.get(itemId);
				if (todo.content !== void 0 && String(todo.content).trim()) current.content = String(todo.content).trim();
				if (todo.status !== void 0 && VALID_STATUSES.has(todo.status)) current.status = todo.status;
			} else {
				const validated = this.validate(todo);
				existing.set(validated.id, validated);
				this.items.push(validated);
			}
		}
		const seen = /* @__PURE__ */ new Set();
		this.items = this.items.map((item) => existing.get(item.id) ?? item).filter((item) => {
			if (seen.has(item.id)) return false;
			seen.add(item.id);
			return true;
		});
		return this.read();
	}
	read() {
		return this.items.map((i) => ({ ...i }));
	}
	validate(todo) {
		const id = String(todo.id ?? "").trim();
		const content = String(todo.content ?? "").trim();
		const statusRaw = todo.status ?? "";
		const status = VALID_STATUSES.has(statusRaw) ? statusRaw : "pending";
		if (!id) throw new Error("Todo item must have an id");
		if (!content) throw new Error("Todo item must have content");
		return {
			id,
			content,
			status
		};
	}
};
function formatTodoList(items) {
	const statusEmoji = {
		pending: "⬜",
		in_progress: "🔄",
		completed: "✅",
		cancelled: "❌"
	};
	const lines = items.map((item) => `${statusEmoji[item.status] ?? "⬜"} [${item.id}] ${item.content} (${item.status})`);
	const total = items.length;
	const completed = items.filter((i) => i.status === "completed").length;
	const inProgress = items.filter((i) => i.status === "in_progress").length;
	return [
		`Todo List (${completed}/${total} done${inProgress > 0 ? `, ${inProgress} in progress` : ""}):`,
		"",
		...lines
	].join("\n");
}
function resolveSessionKey(getSessionKey) {
	const raw = getSessionKey();
	const s = raw != null ? String(raw).trim() : "";
	return s.length > 0 ? s : "default";
}
/**
* In-session task list for multi-step work. One {@link TodoStore} per session key.
*/
function createTodoTool(options) {
	const getSessionKey = options?.getSessionKey ?? (() => "default");
	const stores = /* @__PURE__ */ new Map();
	const getStore = () => {
		const key = resolveSessionKey(getSessionKey);
		let s = stores.get(key);
		if (!s) {
			s = new TodoStore();
			stores.set(key, s);
		}
		return s;
	};
	return {
		name: "todo",
		label: "📋 Todo",
		description: "Plan and track tasks for complex multi-step work.\n\nUSAGE:\n- Provide `todos` array to write/update tasks\n- Omit `todos` to read the current list\n- Set `merge: true` to update existing items by id without replacing the whole list\n- Each item needs: id (unique string), content (task description), status\n- Valid statuses: pending, in_progress, completed, cancelled\n\nWHEN TO USE:\n- At the start of complex tasks (3+ steps) to plan your approach\n- After completing each step to update progress\n- When the user asks about progress or remaining work\n\nBEST PRACTICES:\n- Keep only one item in_progress at a time\n- Use merge=true to update status without rewriting the whole list\n- Create concrete, actionable items (not vague goals)",
		parameters: TodoSchema,
		async execute(_toolCallId, params, _signal) {
			const store = getStore();
			try {
				if (params.todos === void 0) {
					const items = store.read();
					return {
						content: [{
							type: "text",
							text: items.length === 0 ? "No todos yet." : formatTodoList(items)
						}],
						details: { items }
					};
				}
				const p = params;
				const items = store.write(p.todos, p.merge ?? false);
				return {
					content: [{
						type: "text",
						text: formatTodoList(items)
					}],
					details: { items }
				};
			} catch (error) {
				return {
					content: [{
						type: "text",
						text: `Error: ${error instanceof Error ? error.message : String(error)}`
					}],
					details: { items: store.read() }
				};
			}
		}
	};
}
//#endregion
export { TodoStore, createTodoTool };

//# sourceMappingURL=todo-tool.js.map