# Terminal UI and toolbox plan This document records the planned terminal UI direction for future mars-nwe administration tools. It is a design note, not a commitment that the runtime implementation already exists. ## Goals mars-nwe should not grow more direct `curses.h` users. The FLAIM test utilities currently show why this matters: an otherwise optional developer/test tool can pull ncurses into the build shape. Future interactive tools such as setup, filer, salvage, metadata repair and backup helpers should share one small TUI layer instead of each choosing a terminal library. The preferred shape is: ```text third_party/termbox2/ pinned MIT terminal/event backend, tag v2.5.0 third_party/iniparser/ pinned MIT INI reader/writer backend, tag v4.2.6 include/core/ini.h shared libnwcore INI API used by server and tools src/core/ini.c mars-nwe INI wrapper/adaptation and policy src/nwtui/ mars-nwe terminal widgets and themes include/nwtui.h public tool-facing TUI API src/nwi18n/ small mars-nwe translation catalog loader include/nwi18n.h public translation lookup API src/nwtoolbox/ multi-call toolbox binary ``` Tool code must call `nwtui_*` and `nwi18n_*`, not the backend directly. The backend now starts with termbox2 behind the `libnwtui` facade. A minimal ANSI backend or another terminal backend can still replace it later without rewriting `nwsetup`, `nwfiler` or `nwsalvage`. Configuration/catalog parsing must not be private to the TUI layer. The shared INI parser/writer belongs in `libnwcore` so that production daemons, setup tools and optional translation catalogs all use one policy. See `doc/NWCORE_INI_PLAN.md`. ## Default look The default visual style should be a coloured DOS/NetWare-like text UI, not a monochrome curses application. Use ASCII borders as the mandatory base so old terminals still work. UTF-8 block graphics may become an optional theme later, but are not required for the design. The existing blue bar tradition in `dosutils/login.c` is the local mars-nwe reference. External DOS file-manager/BBS screenshots can be used as visual inspiration for blue panels, cyan/bright borders, highlighted menu items and a fixed help line, but should not be copied verbatim. A typical screen should have this structure: ```text +------------------------------------------------------------------------------+ | MARS-NWE Toolbox 0.99 Server: MARS SYS: OK IPX: L2 | +------------------------------------------------------------------------------+ | Setup | Filer | Salvage | Metadata | Backup | Logs | Exit | +------------------------------------------------------------------------------+ +------------------------------+ +----------------------------------------+ | Setup steps | | Networking | | | | IPX backend: L2 Ethernet II | | > Configure server name | | Interface: eth0 | | Configure IPX | | Network: 0x00000002 | | Configure volumes | | | +------------------------------+ +----------------------------------------+ +---------------------------+ | Running: validate config | | Status : waiting | +---------------------------+ +------------------------------------------------------------------------------+ | F1 Help | Enter Select | Esc Back | Tab Next | Alt+S Setup | +------------------------------------------------------------------------------+ ``` The header should be wider and calmer than very compact DOS file managers: 1. header/version/system-status line; 2. top menu or wizard step line; 3. content/work area with panels, forms, lists or dialogs; 4. optional right/bottom running-action box; 5. bottom help/status line. ## Theme roles Tools should never hard-code raw colours. They should request style roles from `nwtui`: ```c typedef enum { NWTUI_STYLE_NORMAL, NWTUI_STYLE_HEADER, NWTUI_STYLE_MENU, NWTUI_STYLE_MENU_SELECTED, NWTUI_STYLE_PANEL, NWTUI_STYLE_PANEL_TITLE, NWTUI_STYLE_STATUS, NWTUI_STYLE_HELP, NWTUI_STYLE_ERROR, NWTUI_STYLE_WARNING, NWTUI_STYLE_OK, NWTUI_STYLE_DISABLED } NwTuiStyle; ``` The first theme should be named `mars-blue`: - header/menu/status bars: blue background; - normal panel background: blue or terminal-default according to capability; - borders: cyan/bright blue; - selected menu/list items: inverted or high-contrast highlight; - help/hotkeys: yellow/bright accent; - errors: red/bright red; - warnings: yellow/brown; - successful/done states: green; - disabled items: dim/grey. ## Navigation widgets Top navigation is a first-class widget. It is used both as a menu and as a wizard-step bar. It should be keyboard reachable and mouse clickable where the backend supports mouse input. Expected behaviour: - Left/Right move between top items; - Alt+hotkey activates a named item; - Enter selects the focused item; - Tab moves between fields/panels; - F1 opens help; - Esc goes back or exits the current modal action; - mouse click selects a top item or panel item if mouse support is enabled. `nwsetup` can use the same widget as a progress/step line, for example: ```text Configuration | Networking | Volumes | Bindery | Logging | Finish ``` The bottom help line should be stable and translated. It should not carry large version text; version and system status belong in the header. ## Multi-call binary The future interactive tools should be built as one multi-call binary, not as several unrelated terminal programs: ```text nwtoolbox main interactive menu nwsetup symlink/hardlink/argv[0] entry to setup mode nwfiler symlink/hardlink/argv[0] entry to filer mode nwsalvage symlink/hardlink/argv[0] entry to salvage mode nwmetadata symlink/hardlink/argv[0] entry to metadata/repair mode nwbackup symlink/hardlink/argv[0] entry to backup/export mode ``` `nwtoolbox` without a specific applet name opens the main menu and lets the user choose setup, filer, salvage, metadata, backup, logs and future tools. If the same binary is invoked through a specific symlink name, it should start that applet directly. This keeps shared UI, translation, config loading and privilege checks in one executable while preserving familiar command names. Conceptual dispatch: ```c int main(int argc, char **argv) { const char *name = nw_basename(argv[0]); if (!strcmp(name, "nwsetup")) return nwtoolbox_run_setup(argc, argv); if (!strcmp(name, "nwfiler")) return nwtoolbox_run_filer(argc, argv); if (!strcmp(name, "nwsalvage")) return nwtoolbox_run_salvage(argc, argv); return nwtoolbox_run_menu(argc, argv); } ``` The applets should share process-wide initialisation: - load configuration; - load translation catalog; - initialise logging; - initialise terminal backend/theme; - check privileges and server paths; - then enter the selected applet. Command-line subcommands may still exist for scripts, but the interactive TUI entry should be the multi-call toolbox. ## Translation without gettext Do not add a gettext dependency just for TUI strings. Use a small mars-nwe translation API. The backing catalog can be an INI-like file, a generated C table, or a small project-owned parser. Tools should not know the storage format. Conceptual API: ```c int nwi18n_load(const char *language, const char *catalog_path); const char *nwi18n_get(const char *key); const char *nwi18n_get_default(const char *key, const char *fallback); ``` Catalog keys should be stable English identifiers, not source strings: ```ini [en] toolbox.title = MARS-NWE Toolbox menu.setup = Setup menu.filer = Filer menu.salvage = Salvage help.main = F1 Help | Enter Select | Esc Back [de] toolbox.title = MARS-NWE Toolbox menu.setup = Setup menu.filer = Filer menu.salvage = Salvage help.main = F1 Hilfe | Enter Auswählen | Esc Zurück ``` The default built-in language should be English. Missing keys fall back to the built-in English string or to the key name in developer builds. ## FLAIM curses replacement path The immediate dependency goal is to remove the ncurses requirement from FLAIM test/tool paths. Do not rewrite every FLAIM utility at once. First isolate the terminal dependency behind `nwtui`, then convert the small curses-using test path to the wrapper. Steps: 1. inventory the current FLAIM test/tool source that includes `curses.h`; 2. add `nwtui` declarations and a minimal backend plan; 3. convert the FLAIM test path from direct curses calls to `nwtui` calls; 4. remove ncurses from that tool path once the converted test compiles; 5. keep PAM/ncurses header extraction in `prepare-local-deps.sh` only while other compile checks still need it. No production daemon should depend on the TUI stack.