refactor(cli): streamline command handling by removing unused methods and simplifying session configuration
This commit is contained in:
@@ -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[]) {
|
||||
|
||||
@@ -33,7 +33,6 @@ class ModernCLI {
|
||||
void PrintCommandSummary() const;
|
||||
|
||||
private:
|
||||
void SetupCommands();
|
||||
void ShowHelp();
|
||||
void ShowCategoryHelp(const std::string& category) const;
|
||||
void ShowCommandSummary() const;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user