refactor(cli): streamline command handling by removing unused methods and simplifying session configuration

This commit is contained in:
scawful
2025-10-12 22:37:31 -04:00
parent 0e6935cf5f
commit 86f85a6afe
7 changed files with 136 additions and 183 deletions

View File

@@ -18,11 +18,6 @@ absl::Status HandleAgentCommand(const std::vector<std::string>& args);
ModernCLI::ModernCLI() {
// Commands are now managed by CommandRegistry singleton
// SetupCommands() is no longer needed
}
void ModernCLI::SetupCommands() {
// No-op: CommandRegistry handles this automatically
}
absl::Status ModernCLI::Run(int argc, char* argv[]) {

View File

@@ -33,7 +33,6 @@ class ModernCLI {
void PrintCommandSummary() const;
private:
void SetupCommands();
void ShowHelp();
void ShowCategoryHelp(const std::string& category) const;
void ShowCommandSummary() const;

View File

@@ -1,6 +1,8 @@
#include "cli/handlers/agent/todo_commands.h"
#include "cli/cli.h"
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
@@ -8,10 +10,11 @@
#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "cli/service/command_registry.h"
#include "app/rom.h"
#include "cli/handlers/agent/common.h"
#include "cli/handlers/agent/todo_commands.h"
#include "cli/handlers/agent/simple_chat_command.h"
#include "cli/handlers/agent/todo_commands.h"
#include "cli/service/command_registry.h"
ABSL_DECLARE_FLAG(bool, quiet);
@@ -20,16 +23,26 @@ namespace cli {
// Forward declarations for special agent commands (not in registry)
namespace agent {
absl::Status HandleRunCommand(const std::vector<std::string>& args, Rom& rom);
absl::Status HandlePlanCommand(const std::vector<std::string>& args);
absl::Status HandleTestCommand(const std::vector<std::string>& args);
absl::Status HandleTestConversationCommand(const std::vector<std::string>& args);
absl::Status HandleLearnCommand(const std::vector<std::string>& args);
absl::Status HandleListCommand();
absl::Status HandleDiffCommand(Rom& rom, const std::vector<std::string>& args);
absl::Status HandleCommitCommand(Rom& rom);
absl::Status HandleRevertCommand(Rom& rom);
absl::Status HandleAcceptCommand(const std::vector<std::string>& args, Rom& rom);
absl::Status HandleDescribeCommand(const std::vector<std::string>& args);
} // namespace agent
namespace {
Rom& AgentRom() {
static Rom rom;
return rom;
}
std::string GenerateAgentHelp() {
auto& registry = CommandRegistry::Instance();
@@ -40,6 +53,11 @@ std::string GenerateAgentHelp() {
help << " simple-chat Interactive AI chat\n";
help << " test-conversation Automated test conversation\n";
help << " plan Generate execution plan\n";
help << " run Execute plan in sandbox\n";
help << " diff Review the latest proposal diff\n";
help << " accept Apply proposal changes to ROM\n";
help << " commit Save current ROM changes\n";
help << " revert Reload ROM from disk\n";
help << " learn Manage learned knowledge\n";
help << " todo Task management\n";
help << " test Run tests\n";
@@ -48,18 +66,20 @@ std::string GenerateAgentHelp() {
// Auto-list available tool commands from registry
help << "Tool Commands (AI can call these):\n";
auto agent_commands = registry.GetAgentCommands();
int count = 0;
for (const auto& cmd : agent_commands) {
if (count++ < 10) { // Show first 10
auto* meta = registry.GetMetadata(cmd);
if (meta) {
help << " " << cmd;
for (size_t i = cmd.length(); i < 24; i++) help << " ";
help << meta->description << "\n";
}
const size_t preview_count = std::min<size_t>(10, agent_commands.size());
for (size_t i = 0; i < preview_count; ++i) {
const auto& cmd = agent_commands[i];
if (auto* meta = registry.GetMetadata(cmd); meta != nullptr) {
help << " " << cmd;
for (size_t pad = cmd.length(); pad < 24; ++pad) help << " ";
help << meta->description << "\n";
}
}
help << " ... and " << (agent_commands.size() - 10) << " more (see z3ed --list-commands)\n\n";
if (agent_commands.size() > preview_count) {
help << " ... and " << (agent_commands.size() - preview_count)
<< " more (see z3ed --list-commands)\n";
}
help << "\n";
help << "Global Options:\n";
help << " --rom=<path> Path to ROM file\n";
@@ -102,10 +122,32 @@ absl::Status HandleAgentCommand(const std::vector<std::string>& arg_vec) {
return registry.Execute("simple-chat", subcommand_args, nullptr);
}
auto& agent_rom = AgentRom();
if (subcommand == "run") {
return agent::HandleRunCommand(subcommand_args, agent_rom);
}
if (subcommand == "plan") {
return agent::HandlePlanCommand(subcommand_args);
}
if (subcommand == "diff") {
return agent::HandleDiffCommand(agent_rom, subcommand_args);
}
if (subcommand == "accept") {
return agent::HandleAcceptCommand(subcommand_args, agent_rom);
}
if (subcommand == "commit") {
return agent::HandleCommitCommand(agent_rom);
}
if (subcommand == "revert") {
return agent::HandleRevertCommand(agent_rom);
}
if (subcommand == "test") {
return agent::HandleTestCommand(subcommand_args);
}
@@ -137,13 +179,6 @@ absl::Status HandleAgentCommand(const std::vector<std::string>& arg_vec) {
return agent::HandleDescribeCommand(subcommand_args);
}
// Placeholder for unimplemented workflow commands
if (subcommand == "run" || subcommand == "diff" || subcommand == "accept" ||
subcommand == "commit" || subcommand == "revert") {
return absl::UnimplementedError(
absl::StrCat("Agent ", subcommand, " command requires ROM context - not yet implemented"));
}
// === Registry Commands (resource, dungeon, overworld, emulator, etc.) ===
auto& registry = CommandRegistry::Instance();
@@ -159,7 +194,7 @@ absl::Status HandleAgentCommand(const std::vector<std::string>& arg_vec) {
absl::StrCat("Unknown agent command: ", subcommand));
}
// Handler functions are now implemented in command_wrappers.cc
// Handler implementations live in general_commands.cc
} // namespace handlers
} // namespace cli

View File

@@ -29,13 +29,11 @@
#include "cli/service/ai/service_factory.h"
#include "cli/service/agent/learned_knowledge_service.h"
#include "cli/service/agent/proposal_executor.h"
#include "cli/service/agent/simple_chat_session.h"
#include "cli/service/planning/proposal_registry.h"
#include "cli/service/planning/tile16_proposal_generator.h"
#include "cli/service/resources/resource_catalog.h"
#include "cli/service/resources/resource_context_builder.h"
#include "cli/service/rom/rom_sandbox_manager.h"
#include "cli/tui/chat_tui.h"
#include "cli/cli.h"
#include "util/macro.h"
@@ -685,124 +683,6 @@ absl::Status HandleDescribeCommand(const std::vector<std::string>& arg_vec) {
return absl::OkStatus();
}
absl::Status HandleChatCommand(Rom& rom) {
RETURN_IF_ERROR(EnsureRomLoaded(rom, "agent chat"));
// Try to load project and labels automatically
auto _ = TryLoadProjectAndLabels(rom); // Ignore errors - we'll use defaults
tui::ChatTUI chat_tui(&rom);
chat_tui.Run();
return absl::OkStatus();
}
absl::Status HandleSimpleChatCommand(const std::vector<std::string>& arg_vec,
Rom* rom, bool quiet) {
RETURN_IF_ERROR(EnsureRomLoaded(*rom, "agent simple-chat"));
auto _ = TryLoadProjectAndLabels(*rom);
std::optional<std::string> batch_file;
std::optional<std::string> single_message;
bool verbose = false;
bool vim_mode = false;
std::optional<std::string> format_option;
for (size_t i = 0; i < arg_vec.size(); ++i) {
const std::string& arg = arg_vec[i];
if (absl::StartsWith(arg, "--file=")) {
batch_file = arg.substr(7);
} else if (arg == "--file" && i + 1 < arg_vec.size()) {
batch_file = arg_vec[++i];
} else if (absl::StartsWith(arg, "--format=")) {
format_option = arg.substr(9);
} else if (arg == "--format" && i + 1 < arg_vec.size()) {
format_option = arg_vec[++i];
} else if (arg == "--json") {
format_option = "json";
} else if (arg == "--markdown" || arg == "--md") {
format_option = "markdown";
} else if (arg == "--compact" || arg == "--raw") {
format_option = "compact";
} else if (arg == "--verbose" || arg == "-v") {
verbose = true;
} else if (arg == "--vim") {
vim_mode = true;
} else if (!absl::StartsWith(arg, "--") && !single_message.has_value()) {
single_message = arg;
}
}
agent::AgentConfig config;
config.verbose = verbose;
config.enable_vim_mode = vim_mode;
if (format_option.has_value()) {
std::string normalized = absl::AsciiStrToLower(*format_option);
if (normalized == "json") {
config.output_format = AgentOutputFormat::kJson;
} else if (normalized == "markdown" || normalized == "md") {
config.output_format = AgentOutputFormat::kMarkdown;
} else if (normalized == "compact" || normalized == "raw") {
config.output_format = AgentOutputFormat::kCompact;
} else if (normalized == "text" || normalized == "friendly" ||
normalized == "pretty") {
config.output_format = AgentOutputFormat::kFriendly;
} else {
return absl::InvalidArgumentError(
absl::StrCat("Unsupported chat format: ", *format_option,
". Supported formats: text, markdown, json, compact"));
}
}
SimpleChatSession session;
session.SetConfig(config);
session.SetRomContext(rom);
if (batch_file.has_value()) {
std::ifstream file(*batch_file);
if (!file.is_open()) {
return absl::NotFoundError(absl::StrCat("Failed to open file: ", *batch_file));
}
if (!quiet) {
std::cout << "Running batch session from: " << *batch_file << std::endl;
std::cout << "----------------------------------------\n\n";
}
std::string line;
int line_num = 0;
while (std::getline(file, line)) {
line_num++;
std::string trimmed_line = std::string(absl::StripAsciiWhitespace(line));
if (trimmed_line.empty() || absl::StartsWith(trimmed_line, "#")) {
continue;
}
if (!quiet) {
std::cout << "Input [" << line_num << "]: " << trimmed_line << std::endl;
}
std::string response;
auto status = session.SendAndWaitForResponse(trimmed_line, &response);
if (!status.ok()) {
std::cerr << "Error processing line " << line_num << ": " << status.message() << std::endl;
continue;
}
std::cout << response << "\n";
if (!quiet) {
std::cout << "\n";
}
}
return absl::OkStatus();
} else if (single_message.has_value()) {
std::string response;
auto status = session.SendAndWaitForResponse(*single_message, &response);
if (!status.ok()) {
return status;
}
std::cout << response << "\n";
return absl::OkStatus();
} else {
return session.RunInteractive();
}
}
absl::Status HandleAcceptCommand(const std::vector<std::string>& arg_vec,
Rom& rom) {
std::optional<std::string> proposal_id;

View File

@@ -1,6 +1,15 @@
#include "cli/handlers/agent/simple_chat_command.h"
#include <optional>
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "cli/service/agent/simple_chat_session.h"
ABSL_DECLARE_FLAG(bool, quiet);
namespace yaze {
namespace cli {
namespace handlers {
@@ -8,28 +17,86 @@ namespace handlers {
absl::Status SimpleChatCommandHandler::Execute(
Rom* rom, const resources::ArgumentParser& parser,
resources::OutputFormatter& formatter) {
agent::SimpleChatSession session;
session.SetRomContext(rom);
// Configure session from parser
agent::AgentConfig config;
if (parser.HasFlag("verbose")) {
config.verbose = true;
config.verbose = parser.HasFlag("verbose");
config.enable_vim_mode = parser.HasFlag("vim");
// Determine desired output format
std::optional<std::string> format_arg = parser.GetString("format");
if (parser.HasFlag("json")) format_arg = "json";
if (parser.HasFlag("markdown") || parser.HasFlag("md")) format_arg = "markdown";
if (parser.HasFlag("compact") || parser.HasFlag("raw")) format_arg = "compact";
auto select_format = [](absl::string_view value)
-> std::optional<agent::AgentOutputFormat> {
std::string normalized = absl::AsciiStrToLower(value);
if (normalized == "json") return agent::AgentOutputFormat::kJson;
if (normalized == "markdown" || normalized == "md") return agent::AgentOutputFormat::kMarkdown;
if (normalized == "compact" || normalized == "raw") return agent::AgentOutputFormat::kCompact;
if (normalized == "text" || normalized == "friendly" || normalized == "pretty") {
return agent::AgentOutputFormat::kFriendly;
}
return std::nullopt;
};
if (format_arg.has_value()) {
if (auto output_format = select_format(*format_arg); output_format.has_value()) {
config.output_format = *output_format;
} else {
return absl::InvalidArgumentError(
absl::StrCat("Unsupported chat format: ", *format_arg,
". Supported formats: text, markdown, json, compact"));
}
} else if (absl::GetFlag(FLAGS_quiet)) {
config.output_format = agent::AgentOutputFormat::kCompact;
}
if (auto format = parser.GetString("format")) {
// Simplified format handling
std::optional<std::string> prompt = parser.GetString("prompt");
auto positional = parser.GetPositional();
for (const auto& token : positional) {
if (token == "-v") {
config.verbose = true;
continue;
}
if (!prompt.has_value() && !token.empty() && token.front() != '-') {
prompt = token;
}
}
session.SetConfig(config);
if (auto file = parser.GetString("file")) {
return session.RunBatch(*file);
} else if (auto prompt = parser.GetString("prompt")) {
std::string response;
return session.SendAndWaitForResponse(*prompt, &response);
} else {
return session.RunInteractive();
if (auto batch = parser.GetString("file")) {
formatter.AddField("mode", "batch");
formatter.AddField("file", *batch);
auto status = session.RunBatch(*batch);
if (status.ok()) {
formatter.AddField("status", "completed");
}
return status;
}
if (prompt.has_value()) {
formatter.AddField("mode", "single");
formatter.AddField("prompt", *prompt);
std::string response;
auto status = session.SendAndWaitForResponse(*prompt, &response);
if (!status.ok()) {
return status;
}
formatter.AddField("response", response);
return absl::OkStatus();
}
formatter.AddField("mode", "interactive");
auto status = session.RunInteractive();
if (status.ok()) {
formatter.AddField("status", "completed");
}
return status;
}
} // namespace handlers

View File

@@ -15,17 +15,11 @@
#include "cli/handlers/graphics/sprite_commands.h"
#include <memory>
#include <unordered_map>
namespace yaze {
namespace cli {
namespace handlers {
// Static command registry
namespace {
std::unordered_map<std::string, resources::CommandHandler*> g_command_registry;
}
std::vector<std::unique_ptr<resources::CommandHandler>> CreateCliCommandHandlers() {
std::vector<std::unique_ptr<resources::CommandHandler>> handlers;
@@ -133,15 +127,6 @@ std::vector<std::unique_ptr<resources::CommandHandler>> CreateAllCommandHandlers
return handlers;
}
resources::CommandHandler* GetCommandHandler(const std::string& name) {
auto it = g_command_registry.find(name);
if (it != g_command_registry.end()) {
return it->second;
}
return nullptr;
}
} // namespace handlers
} // namespace cli
} // namespace yaze

View File

@@ -94,14 +94,6 @@ std::vector<std::unique_ptr<resources::CommandHandler>> CreateAgentCommandHandle
*/
std::vector<std::unique_ptr<resources::CommandHandler>> CreateAllCommandHandlers();
/**
* @brief Get a command handler by name
*
* @param name Command name (e.g., "resource-list", "hex-read")
* @return Pointer to command handler or nullptr if not found
*/
resources::CommandHandler* GetCommandHandler(const std::string& name);
} // namespace handlers
} // namespace cli
} // namespace yaze