refactor: Update CMake configurations and enhance TODO management features
- Replaced `${CMAKE_SOURCE_DIR}` with `${PROJECT_SOURCE_DIR}` in CMake files for consistent path handling.
- Introduced new `todo_commands` and `todo_manager` components to manage TODO items, including creation, listing, updating, and deletion functionalities.
- Added detailed implementations for handling TODO commands in the CLI, improving task management capabilities.
- Enhanced the `TodoManager` class to support persistence and execution planning for TODO items.
- Updated CMake configurations to include new source files related to TODO management, ensuring proper integration into the build system.
This commit is contained in:
302
src/cli/handlers/agent/todo_commands.cc
Normal file
302
src/cli/handlers/agent/todo_commands.cc
Normal file
@@ -0,0 +1,302 @@
|
||||
#include "cli/handlers/agent/todo_commands.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "cli/service/agent/todo_manager.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace cli {
|
||||
namespace handlers {
|
||||
|
||||
namespace {
|
||||
|
||||
using agent::TodoItem;
|
||||
using agent::TodoManager;
|
||||
|
||||
// Global TODO manager instance
|
||||
TodoManager& GetTodoManager() {
|
||||
static TodoManager manager;
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
auto status = manager.Initialize();
|
||||
if (!status.ok()) {
|
||||
std::cerr << "Warning: Failed to initialize TODO manager: "
|
||||
<< status.message() << std::endl;
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
void PrintTodo(const TodoItem& item, bool detailed = false) {
|
||||
std::string status_emoji;
|
||||
switch (item.status) {
|
||||
case TodoItem::Status::PENDING: status_emoji = "⏳"; break;
|
||||
case TodoItem::Status::IN_PROGRESS: status_emoji = "🔄"; break;
|
||||
case TodoItem::Status::COMPLETED: status_emoji = "✅"; break;
|
||||
case TodoItem::Status::BLOCKED: status_emoji = "🚫"; break;
|
||||
case TodoItem::Status::CANCELLED: status_emoji = "❌"; break;
|
||||
}
|
||||
|
||||
std::cout << absl::StreamFormat("[%s] %s %s",
|
||||
item.id,
|
||||
status_emoji,
|
||||
item.description);
|
||||
|
||||
if (!item.category.empty()) {
|
||||
std::cout << absl::StreamFormat(" [%s]", item.category);
|
||||
}
|
||||
|
||||
if (item.priority > 0) {
|
||||
std::cout << absl::StreamFormat(" (priority: %d)", item.priority);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
if (detailed) {
|
||||
std::cout << " Status: " << item.StatusToString() << std::endl;
|
||||
std::cout << " Created: " << item.created_at << std::endl;
|
||||
std::cout << " Updated: " << item.updated_at << std::endl;
|
||||
|
||||
if (!item.dependencies.empty()) {
|
||||
std::cout << " Dependencies: " << absl::StrJoin(item.dependencies, ", ") << std::endl;
|
||||
}
|
||||
|
||||
if (!item.tools_needed.empty()) {
|
||||
std::cout << " Tools needed: " << absl::StrJoin(item.tools_needed, ", ") << std::endl;
|
||||
}
|
||||
|
||||
if (!item.notes.empty()) {
|
||||
std::cout << " Notes: " << item.notes << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
absl::Status HandleTodoCreate(const std::vector<std::string>& args) {
|
||||
if (args.empty()) {
|
||||
return absl::InvalidArgumentError("Usage: agent todo create <description> [--category=<cat>] [--priority=<n>]");
|
||||
}
|
||||
|
||||
std::string description = args[0];
|
||||
std::string category;
|
||||
int priority = 0;
|
||||
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
if (args[i].find("--category=") == 0) {
|
||||
category = args[i].substr(11);
|
||||
} else if (args[i].find("--priority=") == 0) {
|
||||
priority = std::stoi(args[i].substr(11));
|
||||
}
|
||||
}
|
||||
|
||||
auto& manager = GetTodoManager();
|
||||
auto result = manager.CreateTodo(description, category, priority);
|
||||
|
||||
if (!result.ok()) {
|
||||
return result.status();
|
||||
}
|
||||
|
||||
std::cout << "Created TODO:" << std::endl;
|
||||
PrintTodo(*result, true);
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status HandleTodoList(const std::vector<std::string>& args) {
|
||||
std::string status_filter;
|
||||
std::string category_filter;
|
||||
|
||||
for (const auto& arg : args) {
|
||||
if (arg.find("--status=") == 0) {
|
||||
status_filter = arg.substr(9);
|
||||
} else if (arg.find("--category=") == 0) {
|
||||
category_filter = arg.substr(11);
|
||||
}
|
||||
}
|
||||
|
||||
auto& manager = GetTodoManager();
|
||||
std::vector<TodoItem> todos;
|
||||
|
||||
if (!status_filter.empty()) {
|
||||
auto status = TodoItem::StringToStatus(status_filter);
|
||||
todos = manager.GetTodosByStatus(status);
|
||||
} else if (!category_filter.empty()) {
|
||||
todos = manager.GetTodosByCategory(category_filter);
|
||||
} else {
|
||||
todos = manager.GetAllTodos();
|
||||
}
|
||||
|
||||
if (todos.empty()) {
|
||||
std::cout << "No TODOs found." << std::endl;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
std::cout << "TODOs (" << todos.size() << "):" << std::endl;
|
||||
for (const auto& item : todos) {
|
||||
PrintTodo(item);
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status HandleTodoUpdate(const std::vector<std::string>& args) {
|
||||
if (args.size() < 2) {
|
||||
return absl::InvalidArgumentError("Usage: agent todo update <id> --status=<status>");
|
||||
}
|
||||
|
||||
std::string id = args[0];
|
||||
std::string new_status_str;
|
||||
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
if (args[i].find("--status=") == 0) {
|
||||
new_status_str = args[i].substr(9);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_status_str.empty()) {
|
||||
return absl::InvalidArgumentError("--status parameter is required");
|
||||
}
|
||||
|
||||
auto new_status = TodoItem::StringToStatus(new_status_str);
|
||||
auto& manager = GetTodoManager();
|
||||
auto status = manager.UpdateStatus(id, new_status);
|
||||
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
std::cout << "Updated TODO " << id << " to status: " << new_status_str << std::endl;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status HandleTodoShow(const std::vector<std::string>& args) {
|
||||
if (args.empty()) {
|
||||
return absl::InvalidArgumentError("Usage: agent todo show <id>");
|
||||
}
|
||||
|
||||
std::string id = args[0];
|
||||
auto& manager = GetTodoManager();
|
||||
auto result = manager.GetTodo(id);
|
||||
|
||||
if (!result.ok()) {
|
||||
return result.status();
|
||||
}
|
||||
|
||||
PrintTodo(*result, true);
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status HandleTodoDelete(const std::vector<std::string>& args) {
|
||||
if (args.empty()) {
|
||||
return absl::InvalidArgumentError("Usage: agent todo delete <id>");
|
||||
}
|
||||
|
||||
std::string id = args[0];
|
||||
auto& manager = GetTodoManager();
|
||||
auto status = manager.DeleteTodo(id);
|
||||
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
std::cout << "Deleted TODO " << id << std::endl;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status HandleTodoClearCompleted(const std::vector<std::string>& args) {
|
||||
auto& manager = GetTodoManager();
|
||||
auto status = manager.ClearCompleted();
|
||||
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
std::cout << "Cleared all completed TODOs" << std::endl;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status HandleTodoNext(const std::vector<std::string>& args) {
|
||||
auto& manager = GetTodoManager();
|
||||
auto result = manager.GetNextActionableTodo();
|
||||
|
||||
if (!result.ok()) {
|
||||
return result.status();
|
||||
}
|
||||
|
||||
std::cout << "Next actionable TODO:" << std::endl;
|
||||
PrintTodo(*result, true);
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status HandleTodoPlan(const std::vector<std::string>& args) {
|
||||
auto& manager = GetTodoManager();
|
||||
auto result = manager.GenerateExecutionPlan();
|
||||
|
||||
if (!result.ok()) {
|
||||
return result.status();
|
||||
}
|
||||
|
||||
auto& plan = *result;
|
||||
if (plan.empty()) {
|
||||
std::cout << "No pending TODOs." << std::endl;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
std::cout << "Execution Plan (" << plan.size() << " tasks):" << std::endl;
|
||||
for (size_t i = 0; i < plan.size(); ++i) {
|
||||
std::cout << absl::StreamFormat("%2d. ", i + 1);
|
||||
PrintTodo(plan[i]);
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
absl::Status HandleTodoCommand(const std::vector<std::string>& args) {
|
||||
if (args.empty()) {
|
||||
std::cerr << "Usage: agent todo <command> [options]" << std::endl;
|
||||
std::cerr << "Commands:" << std::endl;
|
||||
std::cerr << " create - Create a new TODO" << std::endl;
|
||||
std::cerr << " list - List all TODOs" << std::endl;
|
||||
std::cerr << " update - Update TODO status" << std::endl;
|
||||
std::cerr << " show - Show TODO details" << std::endl;
|
||||
std::cerr << " delete - Delete a TODO" << std::endl;
|
||||
std::cerr << " clear-completed - Clear completed TODOs" << std::endl;
|
||||
std::cerr << " next - Get next actionable TODO" << std::endl;
|
||||
std::cerr << " plan - Generate execution plan" << std::endl;
|
||||
return absl::InvalidArgumentError("No command specified");
|
||||
}
|
||||
|
||||
std::string subcommand = args[0];
|
||||
std::vector<std::string> subargs(args.begin() + 1, args.end());
|
||||
|
||||
if (subcommand == "create") {
|
||||
return HandleTodoCreate(subargs);
|
||||
} else if (subcommand == "list") {
|
||||
return HandleTodoList(subargs);
|
||||
} else if (subcommand == "update") {
|
||||
return HandleTodoUpdate(subargs);
|
||||
} else if (subcommand == "show") {
|
||||
return HandleTodoShow(subargs);
|
||||
} else if (subcommand == "delete") {
|
||||
return HandleTodoDelete(subargs);
|
||||
} else if (subcommand == "clear-completed") {
|
||||
return HandleTodoClearCompleted(subargs);
|
||||
} else if (subcommand == "next") {
|
||||
return HandleTodoNext(subargs);
|
||||
} else if (subcommand == "plan") {
|
||||
return HandleTodoPlan(subargs);
|
||||
} else {
|
||||
return absl::InvalidArgumentError(
|
||||
absl::StrFormat("Unknown todo command: %s", subcommand));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace handlers
|
||||
} // namespace cli
|
||||
} // namespace yaze
|
||||
32
src/cli/handlers/agent/todo_commands.h
Normal file
32
src/cli/handlers/agent/todo_commands.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef YAZE_CLI_HANDLERS_AGENT_TODO_COMMANDS_H_
|
||||
#define YAZE_CLI_HANDLERS_AGENT_TODO_COMMANDS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace cli {
|
||||
namespace handlers {
|
||||
|
||||
/**
|
||||
* @brief Handle z3ed agent todo commands
|
||||
*
|
||||
* Commands:
|
||||
* agent todo create <description> [--category=<cat>] [--priority=<n>]
|
||||
* agent todo list [--status=<status>] [--category=<cat>]
|
||||
* agent todo update <id> --status=<status>
|
||||
* agent todo show <id>
|
||||
* agent todo delete <id>
|
||||
* agent todo clear-completed
|
||||
* agent todo next
|
||||
* agent todo plan
|
||||
*/
|
||||
absl::Status HandleTodoCommand(const std::vector<std::string>& args);
|
||||
|
||||
} // namespace handlers
|
||||
} // namespace cli
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_CLI_HANDLERS_AGENT_TODO_COMMANDS_H_
|
||||
Reference in New Issue
Block a user