# tui_continuous integration plan for n_signer ## Goal Adopt the `tui_continuous` style from `/home/user/lt/aesthetics` with minimal-risk restructuring: - keep caller-owned poll loop and line-input model - avoid ncurses/event-loop inversion - preserve non-interactive behavior and test compatibility ## Scope ### 1) Vendor and wire library - Vendor `tui_continuous.c/.h` into this repository under a stable path (planned: `resources/tui_continuous/`). - Add include path and source wiring to: - `Makefile` dev build - targets that link `src/main.c` (notably integration path) - static build flow (`build_static.sh`, Alpine musl path) ### 2) Main-screen TUI adapter in `src/main.c` - Introduce a small adapter layer that owns: - persistent `TuiFrame` (`app_name=nsigner`, `app_version=NSIGNER_VERSION`, breadcrumb) - hotkey menu definitions matching existing behavior (`q/x`, `l`, `r`, `A`) - status text composition (`locked/unlocked`, words, socket, derived, auto-approve) ### 3) Replace legacy `render_status()` with `tui_continuous` - Use `tui_render_screen()` for top framing/menu/status strip. - Render roles with `tui_render_table()` using columns: - role name - purpose - curve - selector - Render activity log (latest first) via `tui_print()`. - Keep prompt anchoring stable with `tui_anchor_prompt()`. ### 4) Resize behavior - Install SIGWINCH handler with `tui_install_resize_handler()` before unix interactive loop. - On each poll tick, if `tui_resize_pending()` is set, repaint current view. ### 5) Approval flow refactor (`src/server.c` + `src/main.c`) - Add server approval callback API in `server.c`: - callback typedef - registration function (`server_set_approval_cb(...)`) - compact request payload struct (caller/method/role/purpose/derivation + optional peer display) - Keep default callback behavior equivalent to existing stdio prompt output for non-TUI and tests. - In `main.c` unix interactive mode, register a TUI-aware callback that: - paints an approval content screen - shows `[y]/[n]/[e]/[a]` options - reads line input (fgets-compatible behavior) - returns policy decision enums - repaints main status screen after decision ### 6) Mnemonic prompt styling - Keep `fgets` input path intact for paste reliability. - Re-style startup and lock/reunlock prompts using `tui_render_content_screen()` + `tui_print()`. ### 7) Output safety boundaries - Keep machine-readable output untouched (client JSON-RPC responses remain raw). - Restrict style updates for non-interactive surfaces to human-facing usage/banner text only. ### 8) Validation - Run/build validation for: - normal dev build - static build flow - existing prompt-related test paths (`NSIGNER_TEST_FORCE_PROMPT`, `NSIGNER_TEST_NONINTERACTIVE_PROMPT`) - Manual visual checks: - narrow/normal/wide terminal widths - live resize behavior - approval prompt arriving during idle and proper redraw afterwards ### 9) Documentation updates - Update `README.md` and security docs where relevant to mention: - adopted TUI style source (`aesthetics/TUI.md`) - vendored `tui_continuous` component/version ## Execution order 1. Vendor library and wire build 2. Implement main screen adapter + rendering 3. Add resize repaint 4. Refactor approval callback plumbing 5. Add TUI approval view in main 6. Re-style mnemonic prompts 7. Validate tests/builds + manual UX checks 8. Update docs ## Non-goals - No ncurses integration - No event loop ownership changes - No changes to transport semantics (`unix`, `stdio`, `qrexec`, `tcp`) - No machine-readable output format changes