yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
cli.cc
Go to the documentation of this file.
1#include "cli/cli.h"
2
3#include <iostream>
4
5#include "absl/strings/str_cat.h"
6#include "absl/strings/str_format.h"
7#include "absl/strings/str_join.h"
10#ifndef __EMSCRIPTEN__
11#include "ftxui/dom/elements.hpp"
12#include "ftxui/dom/table.hpp"
13#endif
14#include "cli/z3ed_ascii_logo.h"
15
16namespace yaze {
17namespace cli {
18
19// Forward declaration
20namespace handlers {
21absl::Status HandleAgentCommand(const std::vector<std::string>& args);
22}
23
25 // Commands are now managed by CommandRegistry singleton
26}
27
28absl::Status ModernCLI::Run(int argc, char* argv[]) {
29 if (argc < 2) {
30 ShowHelp();
31 return absl::OkStatus();
32 }
33
34 std::vector<std::string> args;
35 for (int i = 1; i < argc; ++i) {
36 args.push_back(argv[i]);
37 }
38
39 if (args[0] == "help") {
40 if (args.size() > 1) {
41 const std::string& target = args[1];
42 auto& registry = CommandRegistry::Instance();
43 if (target == "all") {
44 std::cout << registry.GenerateCompleteHelp() << "\n";
45 } else if (registry.HasCommand(target)) {
46 std::cout << registry.GenerateHelp(target) << "\n";
47 } else {
48 ShowCategoryHelp(target);
49 }
50 } else {
51 ShowHelp();
52 }
53 return absl::OkStatus();
54 }
55
56 // Special case: "agent" command routes to HandleAgentCommand
57 if (args[0] == "agent") {
58 std::vector<std::string> agent_args(args.begin() + 1, args.end());
59 return handlers::HandleAgentCommand(agent_args);
60 }
61
62 // Use CommandRegistry for unified command execution
63 auto& registry = CommandRegistry::Instance();
64
65 std::string command_name = args[0];
66 std::vector<std::string> command_args(args.begin() + 1, args.end());
67
68 if (registry.HasCommand(command_name)) {
69 return registry.Execute(command_name, command_args, nullptr);
70 }
71
72 return absl::NotFoundError(absl::StrCat("Unknown command: ", command_name));
73}
74
76 auto& registry = CommandRegistry::Instance();
77 auto categories = registry.GetCategories();
78
79#ifndef __EMSCRIPTEN__
80 using namespace ftxui;
81
82 auto banner = text("🎮 Z3ED - AI-Powered ROM Editor CLI") | bold | center;
83
84 std::vector<std::vector<std::string>> rows;
85 rows.push_back({"Category", "Commands", "Description"});
86
87 // Add special "agent" category first
88 rows.push_back({"agent", "simple-chat, plan, run, todo, test",
89 "AI agent workflows + tool routing"});
90
91 // Add registry categories
92 for (const auto& category : categories) {
93 auto commands = registry.GetCommandsInCategory(category);
94 std::string cmd_list = commands.size() > 3
95 ? absl::StrCat(commands.size(), " commands")
96 : absl::StrJoin(commands, ", ");
97
98 std::string desc;
99 if (category == "resource")
100 desc = "ROM resource inspection";
101 else if (category == "dungeon")
102 desc = "Dungeon editing";
103 else if (category == "overworld")
104 desc = "Overworld editing";
105 else if (category == "emulator")
106 desc = "Emulator debugging";
107 else if (category == "graphics")
108 desc = "Graphics/palette/sprites";
109 else if (category == "gui")
110 desc = "GUI automation";
111 else if (category == "game")
112 desc = "Messages/dialogue/music";
113 else if (category == "rom")
114 desc = "ROM inspection/validation";
115 else if (category == "test")
116 desc = "Test discovery/execution";
117 else if (category == "tools")
118 desc = "Utilities and doctor tools";
119 else
120 desc = category + " commands";
121
122 rows.push_back({category, cmd_list, desc});
123 }
124
125 Table summary(rows);
126 summary.SelectAll().Border(LIGHT);
127 summary.SelectRow(0).Decorate(bold);
128
129 auto layout = vbox(
130 {text(yaze::cli::GetColoredLogo()), banner, separator(), summary.Render(),
131 separator(),
132 text(absl::StrFormat("Total: %zu commands across %zu categories",
133 registry.Count(), categories.size() + 1)) |
134 center | dim,
135 text("Try `z3ed agent simple-chat` for AI-powered ROM inspection") |
136 center,
137 text("Use `z3ed --list-commands` for complete list") | dim | center});
138
139 auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(layout));
140 Render(screen, layout);
141 screen.Print();
142#else
143 // Simple text output for WASM builds
144 std::cout << yaze::cli::GetColoredLogo() << "\n";
145 std::cout << "Z3ED - AI-Powered ROM Editor CLI\n\n";
146 std::cout << "Categories:\n";
147 std::cout << " agent - AI conversational agent + debugging tools\n";
148 for (const auto& category : categories) {
149 auto commands = registry.GetCommandsInCategory(category);
150 std::cout << " " << category << " - " << commands.size() << " commands\n";
151 }
152 std::cout << "\nTotal: " << registry.Count() << " commands\n";
153 std::cout << "Use 'help <category>' for more details.\n";
154#endif
155}
156
157void ModernCLI::ShowCategoryHelp(const std::string& category) const {
158 auto& registry = CommandRegistry::Instance();
159 auto commands = registry.GetCommandsInCategory(category);
160
161#ifndef __EMSCRIPTEN__
162 using namespace ftxui;
163
164 std::vector<std::vector<std::string>> rows;
165 rows.push_back({"Command", "Description", "Requirements"});
166
167 for (const auto& cmd_name : commands) {
168 auto* metadata = registry.GetMetadata(cmd_name);
169 if (metadata) {
170 std::string requirements;
171 if (metadata->requires_rom)
172 requirements += "ROM ";
173 if (metadata->requires_grpc)
174 requirements += "gRPC ";
175 if (requirements.empty())
176 requirements = "—";
177
178 rows.push_back({cmd_name, metadata->description, requirements});
179 }
180 }
181
182 if (rows.size() == 1) {
183 rows.push_back({"—", "No commands in this category", "—"});
184 }
185
186 Table detail(rows);
187 detail.SelectAll().Border(LIGHT);
188 detail.SelectRow(0).Decorate(bold);
189
190 auto layout =
191 vbox({text(absl::StrCat("Category: ", category)) | bold | center,
192 separator(), detail.Render(), separator(),
193 text("Commands are auto-registered from CommandRegistry") | dim |
194 center});
195
196 auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(layout));
197 Render(screen, layout);
198 screen.Print();
199#else
200 // Simple text output for WASM builds
201 std::cout << "Category: " << category << "\n\n";
202 for (const auto& cmd_name : commands) {
203 auto* metadata = registry.GetMetadata(cmd_name);
204 if (metadata) {
205 std::cout << " " << cmd_name << " - " << metadata->description << "\n";
206 }
207 }
208 if (commands.empty()) {
209 std::cout << " No commands in this category.\n";
210 }
211#endif
212}
213
215 auto& registry = CommandRegistry::Instance();
216 auto categories = registry.GetCategories();
217
218#ifndef __EMSCRIPTEN__
219 using namespace ftxui;
220
221 std::vector<std::vector<std::string>> rows;
222 rows.push_back({"Command", "Category", "Description"});
223
224 for (const auto& category : categories) {
225 auto commands = registry.GetCommandsInCategory(category);
226 for (const auto& cmd_name : commands) {
227 auto* metadata = registry.GetMetadata(cmd_name);
228 if (metadata) {
229 rows.push_back({cmd_name, metadata->category, metadata->description});
230 }
231 }
232 }
233
234 if (rows.size() == 1) {
235 rows.push_back({"—", "—", "No commands registered"});
236 }
237
238 Table command_table(rows);
239 command_table.SelectAll().Border(LIGHT);
240 command_table.SelectRow(0).Decorate(bold);
241
242 auto layout =
243 vbox({text("Z3ED Command Summary") | bold | center, separator(),
244 command_table.Render(), separator(),
245 text(absl::StrFormat("Total: %zu commands across %zu categories",
246 registry.Count(), categories.size())) |
247 center | dim,
248 text("Use `z3ed --tui` for interactive command palette.") | center |
249 dim});
250
251 auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(layout));
252 Render(screen, layout);
253 screen.Print();
254#else
255 // Simple text output for WASM builds
256 std::cout << "Z3ED Command Summary\n\n";
257 for (const auto& category : categories) {
258 auto commands = registry.GetCommandsInCategory(category);
259 for (const auto& cmd_name : commands) {
260 auto* metadata = registry.GetMetadata(cmd_name);
261 if (metadata) {
262 std::cout << " " << cmd_name << " [" << metadata->category << "] - "
263 << metadata->description << "\n";
264 }
265 }
266 }
267 std::cout << "\nTotal: " << registry.Count() << " commands across "
268 << categories.size() << " categories\n";
269#endif
270}
271
273 const_cast<ModernCLI*>(this)->ShowHelp();
274}
275
276void ModernCLI::PrintCategoryHelp(const std::string& category) const {
277 const_cast<ModernCLI*>(this)->ShowCategoryHelp(category);
278}
279
281 const_cast<ModernCLI*>(this)->ShowCommandSummary();
282}
283
284} // namespace cli
285} // namespace yaze
static CommandRegistry & Instance()
absl::Status Run(int argc, char *argv[])
Definition cli.cc:28
void PrintCategoryHelp(const std::string &category) const
Definition cli.cc:276
void PrintCommandSummary() const
Definition cli.cc:280
void ShowCategoryHelp(const std::string &category) const
Definition cli.cc:157
void ShowCommandSummary() const
Definition cli.cc:214
void PrintTopLevelHelp() const
Definition cli.cc:272
void ShowHelp()
Definition cli.cc:75
Definition cli.h:17
absl::Status HandleAgentCommand(const std::vector< std::string > &args)
Unified agent command handler using CommandRegistry.
Definition agent.cc:112
std::string GetColoredLogo()