feat(lite): make the Console tab interactive (run backend commands)

The lite backend's litelib_execute() is the same command interface as
silentdragonxlite-cli (balance, info, height, list, notes, addresses, sync,
syncstatus, new, send, shield, encrypt, …), so the lite Console can be a real
interactive console — like the full-node RPC console — instead of a read-only
diagnostics log.

Controller: add an async arbitrary-command runner mirroring the broadcast
pattern — runConsoleCommand() splits "<command> [args]" (the first token is the
command, the remainder is passed as the single arg string litelib_execute
expects, since it does NOT whitespace-split), runs the bridge call on a detached
thread that captures the shared bridge (never `this`), and delivers the result
to a main-thread slot drained by takeConsoleResult(). Results are NEVER routed
through LiteDiagnostics (seed/export can return secrets).

Console tab: a command input (Enter to run, Up/Down history via the shared
console_input_model helpers) over a unified scroll buffer that interleaves the
automatic diagnostics events with user command I/O, colour-coded, with the live
status header preserved. The input is disabled while a command runs.

Two backend footguns are intercepted at the UI layer before forwarding:
`clear` (the backend command WIPES wallet tx history — re-bound to clearing the
view, what the user expects) and `quit`/`exit` (would only save; the embedded
backend must stay running with the app).

Test: runConsoleCommand drives the fake backend (info -> raw response; "new zs"
-> exercises the command/arg split; blank line rejected).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 20:32:03 -05:00
parent c8183241c3
commit 4a65dce947
5 changed files with 294 additions and 26 deletions

View File

@@ -1108,12 +1108,16 @@ void I18n::loadBuiltinEnglish()
// --- Lite Network tab (server browser) ---
strings_["lite_console_title"] = "Console";
strings_["lite_console_intro"] = "Diagnostic log: server connections, wallet open/create, and sync events.";
strings_["lite_console_intro"] = "Diagnostic log + interactive console. Type a command (e.g. info, balance, list) and press Enter; type help for the full list.";
strings_["lite_console_status"] = "Status:";
strings_["lite_console_clear"] = "Clear";
strings_["lite_console_copy"] = "Copy";
strings_["lite_console_autoscroll"] = "Auto-scroll";
strings_["lite_console_empty"] = "No diagnostic output yet.";
strings_["lite_console_empty"] = "No output yet. Type a command (try 'help') and press Enter.";
strings_["lite_console_input_hint"] = "Type a command (help, info, balance, list, sync, new zs)…";
strings_["lite_console_running"] = "running…";
strings_["lite_console_busy"] = "A command is already running — wait for it to finish.";
strings_["lite_console_quit_note"] = "'quit'/'exit' don't apply here — the embedded backend stays running with the app.";
strings_["lite_net_title"] = "Lite Servers";
strings_["lite_net_intro"] = "Pick a server to use, or let the wallet choose one at random. Changes apply immediately.";
strings_["lite_net_use_random"] = "Use a random server each time";