refactor(console): unify lite + full-node console behind a pluggable executor

The two consoles were separate implementations (the rich full-node ConsoleTab and a
minimal RenderLiteConsoleTab). Introduce ConsoleCommandExecutor to abstract the only
real differences — command execution + log source — so both variants share the one rich
terminal (the lite console now gains selection, zoom, copy, and JSON-colored output).

- console_command_executor.{h,cpp}: interface + FullNodeConsoleExecutor (dragonxd log
  ingestion + RPC command execution, result queue) and LiteConsoleExecutor (lite
  diagnostics ring + backend runConsoleCommand/takeConsoleResult, connection/sync status).
- ConsoleTab::render() now takes a ConsoleCommandExecutor&; log ingestion, command
  submission, and command results flow through it. The RPC command-reference popup and
  the daemon/errors/rpc-trace/app filter toggles are gated on the executor's capabilities;
  the toolbar status dot + a status header come from the executor.
- Safety preserved: `clear`/`cls` is intercepted as a view-only clear in the shared UI so
  it is NEVER forwarded (the lite backend's `clear` wipes tx history); command output is
  not persisted to diagnostics.
- App owns the executor (created per variant) and routes both NavPages to console_tab_;
  lite_console_tab.{h,cpp} deleted.

Needs runtime verification of BOTH consoles (full-node RPC + lite: clear, seed/export
secrecy, sync status, command results).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 15:59:17 -05:00
parent 1266b6e68e
commit b5001ad4db
10 changed files with 594 additions and 570 deletions

View File

@@ -18,23 +18,23 @@
namespace dragonx {
namespace ui {
class ConsoleCommandExecutor;
/**
* @brief Console tab for daemon output and command input
*
* Shows dragonxd output and allows executing RPC commands.
* @brief Console tab — a rich terminal shared by the full-node and lite variants.
*
* The command execution + log sources are provided by a ConsoleCommandExecutor, so this
* one widget serves both dragonxd (RPC) and the lite backend.
*/
class ConsoleTab {
public:
ConsoleTab();
~ConsoleTab();
/**
* @brief Render the console tab
* @param daemon Pointer to embedded daemon (may be null)
* @param rpc Pointer to RPC client for command execution
* @param xmrig Pointer to xmrig manager for pool mining output (may be null)
* @brief Render the console tab against a backend executor.
*/
void render(daemon::EmbeddedDaemon* daemon, rpc::RPCClient* rpc, rpc::RPCWorker* worker, daemon::XmrigManager* xmrig = nullptr);
void render(ConsoleCommandExecutor& exec);
/**
* @brief Render the RPC Command Reference popup at top-level scope.
@@ -93,11 +93,13 @@ private:
ImU32 color;
};
void executeCommand(const std::string& cmd, rpc::RPCClient* rpc, rpc::RPCWorker* worker);
void addCommandResult(const std::string& cmd, const std::string& result, bool is_error = false);
void renderToolbar(daemon::EmbeddedDaemon* daemon);
// Format + color a completed command result (JSON-aware) into console lines.
void addFormattedResult(const std::string& result, bool is_error);
void renderStatusHeader(ConsoleCommandExecutor& exec);
void renderToolbar(ConsoleCommandExecutor& exec);
void renderOutput();
void renderInput(rpc::RPCClient* rpc, rpc::RPCWorker* worker);
void renderInput(ConsoleCommandExecutor& exec);
void renderCommandsPopup();
// Selection helpers
@@ -123,12 +125,8 @@ private:
bool scroll_to_bottom_ = false;
float scroll_up_cooldown_ = 0.0f; // seconds to wait before re-enabling auto-scroll
int new_lines_since_scroll_ = 0; // new lines while scrolled up (for indicator)
size_t last_daemon_output_size_ = 0;
size_t last_xmrig_output_size_ = 0;
bool shown_startup_message_ = false;
daemon::EmbeddedDaemon::State last_daemon_state_ = daemon::EmbeddedDaemon::State::Stopped;
bool last_rpc_connected_ = false;
// (log-ingestion cursors + result queue moved to the ConsoleCommandExecutor)
// Text selection state
bool is_selecting_ = false;
bool has_selection_ = false;