# Efficient professional TUI redesign ## Problem Statement `proxyctl` is functionally capable, but its current terminal interface is an unbounded plain-text document rather than an efficient operational dashboard. Routine use requires navigating away from the Target panel to switch the Active Profile, long descriptions and errors compete with the Target list, and operations temporarily block useful browsing. The interface does not respond to terminal size, scroll long content, provide mature field editing, or present consistent focus, status, confirmation, and error behavior. The visual hierarchy is too weak for users to assess configuration health at a glance. Target states are plain bracketed words, Profile markers are unexplained, errors are styled inconsistently, and busy or deferred-exit states are not always visible. The static Help page and long lists can extend beyond the terminal with no viewport. Profile fields support only appending and backspacing, making correction of long URLs and Bypass rules unnecessarily slow. Some actions are also described too generically. In particular, treating every Target action as a toggle hides the meaningful difference between enabling a Disabled Target, applying an Active Profile to an External Target, and performing Drift Resolution on a Drifted Target. ## Solution Redesign the TUI as a keyboard-only, responsive, professional dashboard optimized for frequent operation. The default wide layout presents a stable Target list beside concise details for the selected Target, with the Active Profile and global Target health summarized in the header. Narrow terminals automatically use a single-column layout without changing the underlying workflows. Use restrained semantic color, standard Unicode symbols, explicit state text, stable focus treatment, contextual actions, scrollable content, structured status feedback, and safe modal dialogs. Color reinforces meaning but is never the sole signal. The interface adapts to light and dark terminals and respects `NO_COLOR`. Make Active Profile switching a first-class main-screen action through a searchable picker, while keeping Profile creation, editing, and deletion in a dedicated management experience. Replace the append-only form with mature text inputs, field-level validation, a parsed Bypass preview, and an explicit Protocol Probe action. Keep system mutations serial and safe while allowing the user to browse the dashboard during an operation. Preserve the existing no-cross-Target-rollback rule, surface partial outcomes directly on Target rows, and focus the first failed Target. Introduce explicit Drift Resolution choices for reapplying the Active Profile or restoring original configuration when ownership evidence permits. Rebuild the presentation layer around Bubble Tea, Bubbles, and Lip Gloss, with separate layout, theme, page, modal, and reusable component responsibilities. Permit focused changes to the Application Interface where required for progressive detection, structured progress, structured errors, and Drift Resolution, while preserving stable Target configuration semantics. ## User Stories 1. As a frequent proxyctl user, I want the default screen optimized for rapid scanning, so that I can understand system proxy state immediately. 2. As a frequent proxyctl user, I want the Active Profile visible in the header, so that I know which Proxy Profile is being applied. 3. As a frequent proxyctl user, I want a global count of Enabled, Disabled, External, and Drifted Targets, so that I can identify abnormal state without inspecting every row. 4. As a frequent proxyctl user, I want Target ordering to remain stable, so that state changes do not move actions beneath my cursor. 5. As a frequent proxyctl user, I want failed Targets focused after a partial operation, so that I can investigate without searching. 6. As a keyboard user, I want every workflow to remain fully operable without a mouse, so that proxyctl works consistently over SSH and in minimal terminals. 7. As a keyboard user, I want familiar arrow and terminal navigation conventions, so that the interface is quick to learn. 8. As a keyboard user, I want Tab to move focus between interactive regions, so that focus changes are explicit. 9. As a keyboard user, I want the focused region visibly highlighted, so that I always know where input will apply. 10. As a keyboard user, I want contextual shortcuts in a fixed footer, so that the most relevant actions remain discoverable. 11. As a keyboard user, I want complete shortcuts available through Help, so that the footer can remain concise. 12. As a user who prefers redesigned shortcuts, I want the new interaction model optimized without preserving every legacy key, so that obsolete constraints do not weaken the redesign. 13. As a user in a wide terminal, I want a Target list and Target details visible side by side, so that selection and explanation do not compete for vertical space. 14. As a user in a narrow terminal, I want the interface to become a usable single-column layout, so that split panes and SSH sessions remain supported. 15. As a user in a terminal smaller than the supported minimum, I want a concise size warning rather than corrupted layout, so that recovery is obvious. 16. As a user who resizes a terminal, I want the layout to update immediately while preserving selection and focus, so that resizing does not reset my work. 17. As a user with long Target details, I want a scrollable details viewport, so that every explanation remains reachable. 18. As a user with many Proxy Profiles, I want scrollable lists, so that selection never moves beyond visible content. 19. As a user opening Help in a short terminal, I want scrollable Help content, so that no instructions are inaccessible. 20. As a user, I want restrained professional styling, so that the interface is polished without becoming visually noisy. 21. As a user, I want standard Unicode or ASCII symbols, so that the interface does not depend on Nerd Font installation. 22. As a user, I want Target states represented by symbols, color, and words together, so that meaning survives monochrome terminals and screenshots. 23. As a user in a light terminal, I want readable contrast, so that styling designed for dark backgrounds does not disappear. 24. As a user in a dark terminal, I want readable contrast, so that the dashboard remains comfortable for long sessions. 25. As a user who sets `NO_COLOR`, I want all meaning retained without color, so that accessibility and terminal preferences are respected. 26. As a user, I want a small recognizable proxyctl title, so that the interface has identity without wasting screen space on a large logo. 27. As a user, I want only Available Targets shown during routine operation, so that absent integrations do not create clutter. 28. As a troubleshooting user, I want to toggle visibility of unavailable Targets, so that detection evidence is available without leaving the dashboard. 29. As a user selecting a Target, I want its state and evidence shown before long documentation, so that the most actionable information appears first. 30. As a user selecting a Target, I want to see what it affects, so that I understand the configuration surface. 31. As a user selecting a Target, I want permission and restart risks highlighted, so that operational consequences are not buried in prose. 32. As a user, I want Disabled Targets to offer an Enable action, so that the operation is unambiguous. 33. As a user, I want Enabled Targets to offer a Disable action, so that the operation is unambiguous. 34. As a user, I want External Targets to offer Apply Profile, so that I understand proxyctl will begin managing that configuration while preserving restorable state. 35. As a user, I want Drifted Targets to offer Drift Resolution, so that the interface does not guess my intended recovery. 36. As a user resolving drift, I want to reapply the Active Profile, so that managed configuration can return to Enabled. 37. As a user resolving drift, I want to restore original configuration when ownership evidence permits, so that I can stop proxyctl management safely. 38. As a user resolving drift without sufficient ownership evidence, I want restoration to fail truthfully and safely, so that external changes are not overwritten. 39. As a user performing a routine reversible Target action, I do not want a confirmation dialog, so that frequent operation remains fast. 40. As a user deleting a Proxy Profile, I want a confirmation dialog, so that destructive actions are deliberate. 41. As a user whose action will restart Docker, I want a high-impact confirmation dialog, so that running work is not disrupted unexpectedly. 42. As a user in a confirmation dialog, I want cancellation to be the safe default, so that accidental confirmation is unlikely. 43. As a user, I want to switch the Active Profile directly from the dashboard, so that routine switching does not require entering management screens. 44. As a user switching Profiles, I want a searchable picker, so that selection remains fast with many Profiles. 45. As a user opening the Profile picker, I want the Active Profile pinned first and other Profiles sorted by name, so that ordering is stable and predictable. 46. As a user, I want Profile switching and Profile management to remain distinct, so that routine activation is not mixed with destructive editing actions. 47. As a user, I want to create, edit, and delete Proxy Profiles in a dedicated management page, so that those workflows have enough space and context. 48. As a user editing a Proxy Profile, I want a real text cursor and insertion editing, so that I can correct text without deleting from the end. 49. As a user editing a Proxy Profile, I want Home, End, Delete, Backspace, and paste behavior, so that terminal text editing is efficient. 50. As a user editing a long URL, I want horizontal scrolling with visible focus, so that the field remains usable in narrow layouts. 51. As a user entering invalid data, I want validation beside the relevant field, so that I know exactly what to fix. 52. As a user correcting a field, I want stale field errors to clear or update, so that the form reflects current input. 53. As a user switching between Single and Advanced Profile modes, I want existing values preserved according to current Profile semantics, so that mode changes do not discard work. 54. As a user entering Bypass rules, I want to paste a comma-separated list, so that common configuration remains fast. 55. As a user entering Bypass rules, I want a live normalized preview, so that deduplication and canonical forms are visible before saving. 56. As a user entering an invalid Bypass rule, I want the specific rule identified, so that one bad entry does not produce an opaque form error. 57. As a user entering proxy credentials, I want passwords obscured while editing and reviewing Profiles, so that shoulder surfing and screenshots do not expose secrets. 58. As a security-conscious user, I want all TUI status, evidence, and error text defensively redacted before rendering, so that a lower layer cannot accidentally expose credentials. 59. As a user with an uncertain endpoint, I want an explicit Protocol Probe action beside the applicable URL field, so that discovery is visible rather than hidden behind an unexplained shortcut. 60. As a user who knows the Protocol Probe shortcut, I want the shortcut retained as an efficient path, so that frequent use remains quick. 61. As a privacy-conscious user, I want Protocol Probe to run only when explicitly requested, so that saving and opening forms never create hidden network traffic. 62. As a user probing an endpoint, I want progress attached to the URL field, so that the operation is connected to its source. 63. As a user probing an endpoint, I want detected HTTP and SOCKS5 capabilities displayed, so that the resulting Profile values are understandable. 64. As a user probing a dual-protocol endpoint, I want a compatible Advanced Profile populated, so that HTTP-only and GNOME Targets can share the Active Profile. 65. As a user whose probe input changes while a probe is running, I want stale results ignored, so that old endpoint results never overwrite new input. 66. As a user launching proxyctl, I want the dashboard to appear immediately with per-Target Checking states, so that slow detection does not look like a hung process. 67. As a user refreshing Targets, I want each Target row to update as detection completes, so that progress is visible incrementally. 68. As a user applying a Target change, I want an in-row spinner and a bottom status message, so that both local and global progress are visible. 69. As a user waiting for a system mutation, I want to navigate Targets and read Help, so that the entire interface is not unnecessarily frozen. 70. As a user waiting for a system mutation, I want conflicting modifications disabled, so that configuration operations remain serialized. 71. As a user attempting a disabled action, I want an explanation of why it is unavailable, so that the interface does not silently ignore input. 72. As a user switching the Active Profile, I want each affected Target to update independently, so that partial progress is truthful. 73. As a user whose Active Profile switch partially fails, I want successful Target updates retained and failed Targets clearly marked, so that the existing no-global-rollback rule is visible. 74. As a user whose Active Profile switch partially fails, I want the error summary preserved until acknowledged, so that the failure is not replaced by a transient success message. 75. As a user completing a successful operation, I want the success notice replaceable by the next operation, so that routine feedback does not require dismissal. 76. As a user receiving an error, I want concise text in the status area and an option to expand current details, so that diagnostics are available without permanently consuming space. 77. As a user, I do not want an in-TUI activity history, so that the interface remains focused on current state. 78. As a troubleshooting user, I want historical operation details to remain in the existing redacted log, so that removing an activity page does not remove diagnostics. 79. As a user pressing Escape, I want the current modal closed or the current page left, so that back navigation is consistent. 80. As a user pressing `q` on a child page, I want to return to the previous page, so that accidental application exit is less likely. 81. As a user pressing `q` on the dashboard, I want to exit, so that the primary quit path remains efficient. 82. As a user pressing Ctrl+C on any page, I want to exit, so that terminal interrupt behavior is consistent. 83. As a user requesting exit during a mutation, I want a visible message that proxyctl will exit safely after completion, so that my input is not silently ignored. 84. As a safety-conscious user, I do not want a system mutation terminated at an arbitrary intermediate step, so that exit does not strand configuration unnecessarily. 85. As a user leaving proxyctl, I want the prior terminal screen restored, so that the dashboard does not leave redraw artifacts in shell history. 86. As a user, I do not want the dashboard to claim that a proxy is online merely because Targets are Enabled, so that configuration state is not confused with connectivity. 87. As a user, I want Protocol Probe results confined to Profile editing, so that handshake capability is not presented as global health or latency. 88. As a maintainer, I want layout, theme, pages, dialogs, and components separated, so that future TUI work does not enlarge one monolithic state machine. 89. As a maintainer, I want mature terminal components for text input, lists, viewports, and spinners, so that common interaction behavior is not reimplemented incompletely. 90. As a maintainer, I want the Application Interface to expose structured progress and Drift Resolution intents, so that the TUI does not infer domain outcomes from display strings. 91. As a maintainer, I want Target Adapter configuration semantics preserved, so that a visual redesign does not destabilize working proxy configuration. 92. As a maintainer, I want each migration phase to leave a runnable TUI, so that the redesign can be verified incrementally. 93. As a maintainer, I want fixed-size rendering tests, so that responsive layouts do not regress silently. 94. As a maintainer, I want behavioral tests to drive the same Model used in production, so that test confidence covers real navigation and rendering composition. 95. As a maintainer, I want long content, resize, focus, modal, and no-color cases tested, so that edge terminals receive deliberate behavior. ## Implementation Decisions - The redesign optimizes first for rapid daily operation and second for polished visual quality. New-user explanation is available contextually but does not dominate the dashboard. - The primary wide-screen layout is a two-pane dashboard with a stable Target list on the left and concise selected-Target details on the right. - Layout is responsive. Terminals at least 100 columns by 28 rows receive the complete two-pane layout. Terminals from 60 through 99 columns use a single-column layout. Terminals smaller than 60 columns or 16 rows receive a compact size warning rather than a broken full interface. - Bubble Tea remains the application runtime. Bubbles supplies mature list, text-input, viewport, and spinner behavior. Lip Gloss supplies semantic styling and responsive composition. - The TUI is decomposed into explicit responsibilities for application state coordination, responsive layout, semantic theme, pages, dialogs, status presentation, and reusable components. The redesign must not continue concentrating all behavior and rendering in one file. - The program uses the terminal alternate screen and restores the previous terminal display on exit. - The interface remains strictly keyboard-only. Mouse handling is out of scope. - Existing shortcuts are not a compatibility contract. The redesign may replace them, while still preferring familiar terminal conventions and displaying contextual help. - Standard Unicode symbols are used for visual status. The interface does not depend on Nerd Font glyphs. ASCII-safe degradation is permitted where terminal capabilities require it. - Target state uses a symbol, semantic color, and explicit word. Color is reinforcement rather than the sole carrier of meaning. - The theme adapts to light and dark terminal backgrounds and respects `NO_COLOR`. Styling is restrained, professional, and low-saturation outside meaningful states and warnings. - The header contains a compact proxyctl identity, the Active Profile, and global Target state counts. It does not contain a large logo, version clutter, latency, or a global connected indicator. - The dashboard shows Available Targets by default. A contextual action toggles unavailable Targets into the same stable list with detection evidence and disabled mutation actions. - Target ordering is fixed by product composition rather than dynamically grouped by state. - Target details prioritize current state, evidence, affected scope, permissions, restart risk, and current contextual action. Longer explanation remains scrollable below those facts. - Tab moves focus between dashboard regions. The focused pane or component has a clear non-color-only focus treatment. Arrow keys act within the focused component. - The footer presents only the most important actions for the current focus and state. Complete contextual keyboard help appears in a scrollable Help dialog. - Active Profile switching is available from the dashboard through a searchable modal picker. The Active Profile is pinned first and remaining Profiles sort by name. - Proxy Profile creation, editing, and deletion remain in a dedicated management page, separate from routine activation. - Profile forms use mature text inputs with insertion, deletion, cursor movement, paste, focus styling, and horizontal scrolling. - Validation is structured by field. A changed field updates or clears stale validation feedback instead of leaving unrelated global errors in place. - Bypass editing accepts efficient delimited text and simultaneously renders normalized, deduplicated entries with item-specific validation. - Protocol Probe is an explicit field action with a keyboard shortcut. It remains user-initiated, never runs on save or form entry, and never becomes a general connectivity or latency test. - Protocol Probe progress and results belong to the field that initiated the probe. Results are invalidated when relevant input or mode changes. - Dual HTTP and SOCKS5 detection creates an Advanced Profile with HTTP transport values for HTTP and HTTPS and a GNOME-compatible SOCKS5 value for ALL/SOCKS, preserving the behavior already established in the current implementation. - Disabled, Enabled, External, and Drifted Targets do not share an ambiguous Toggle label. Their primary actions are Enable, Disable, Apply Profile, and Resolve respectively. - Drift Resolution is explicit. It offers reapplication of the Active Profile and restoration of original configuration when ownership evidence permits. Failed ownership checks remain truthful failures and never overwrite externally changed state. - Confirmation dialogs are limited to destructive Profile deletion and disruptive Docker restart paths, including Active Profile switches that require that restart. Cancellation is the default focus. - Target detection at startup and refresh is progressive. The dashboard appears immediately, each Target begins in a Checking state, and rows update independently. - Mutations remain serialized. During a mutation, browsing, selection, details, and Help remain usable, while conflicting mutations and management actions are disabled with an explanation. - Per-Target and Active Profile operations expose structured progress rather than requiring the TUI to parse notice strings. - Active Profile transitions retain successful Target updates when another Target fails. There is no cross-Target rollback. The first failed Target is selected, row states remain truthful, and the current error summary remains visible. - A successful status may be replaced by subsequent activity. An error remains until acknowledged or superseded by an explicit successful resolution of that error. - Current error details may be expanded, but the TUI does not add an activity-history page. Existing bounded, redacted operation logging remains the historical diagnostic surface. - All text crossing into the TUI is defensively redacted immediately before rendering, in addition to lower-layer redaction. - Escape closes a dialog or returns one level. `q` returns from child pages and exits from the dashboard. Ctrl+C requests exit from every page. - Exit during a system operation is deferred until the operation reaches a safe completion. The UI explicitly displays the pending-exit state and rejects new work. - Selection, focus, viewport position, and active dialogs survive terminal resize whenever their referenced item still exists. - The Application Interface may change to represent progressive detection, structured progress, structured current errors, action availability, and Drift Resolution. These changes must remain independent of Bubble Tea presentation types. - Stable Target Adapter configuration and restoration semantics are not redesigned as part of this effort. - Migration proceeds in runnable stages: responsive/theme foundation; dashboard; Profile picker and management; forms/dialogs/Help; status, accessibility, and consistency completion. A long-lived legacy/new TUI switch is not introduced. ## Testing Decisions - Tests assert externally observable behavior through the highest practical seam rather than component implementation, Lip Gloss calls, or private state layout. - The primary seam is the complete TUI Model with an injected fake Application Module. Tests send terminal resize messages, keyboard messages, asynchronous progress messages, and completion results, then assert rendered semantics, focus, visible actions, emitted intents, and navigation outcomes. - Fixed-size render snapshots are produced through the complete Model at representative sizes: a wide 120×36 dashboard, an 80×24 single-column layout, and a 59×15 below-minimum layout. - Render coverage includes light, dark, and `NO_COLOR` modes. Assertions must not rely only on raw ANSI sequences; semantic text and layout remain testable without color. - The secondary seam is the Application Interface. It tests progressive detection, structured progress, serialized mutation, Drift Resolution choices, safe restore refusal, and partial Active Profile transition behavior. - Existing Application Module tests for progressive Profile activation, partial failure without rollback, confirmation, and Target state coordination are prior art and should be extended rather than duplicated at lower seams. - Existing TUI tests that submit keys and inspect rendered output are prior art for the primary seam. They should migrate to the new layout contract rather than preserving obsolete literal views. - Target Adapter tests remain responsible for actual configuration translation, ownership, restoration, permissions, and command sequencing. The redesign does not duplicate those tests in the TUI. - Bubbles and Lip Gloss internals are not unit tested. Small component tests are added only when a pure input boundary cannot be exercised deterministically through the complete Model. - Responsive tests cover resizing in both directions while retaining valid selection, focus, viewport, in-flight state, and dialogs. - List and viewport tests cover enough Targets, Profiles, Help text, and detail text to exceed terminal height. - Content tests cover long Target names, long evidence, long redacted errors, long URLs, long Profile names, and many Bypass entries. - Form tests cover insertion, cursor movement, deletion, paste, horizontal scrolling, field navigation, Single/Advanced transitions, inline validation, Bypass normalization preview, save, and cancel. - Protocol Probe tests cover explicit invocation, in-field progress, HTTP-only, SOCKS5-only, dual-protocol population, failure, unrecognized protocol, credential-safe status, and stale-result invalidation after edits or mode changes. - Status tests cover replaceable success, persistent errors, expanded current details, disabled-action explanations, deferred exit, and removal of stale status after a successful resolution. - Action tests cover contextual Enable, Disable, Apply Profile, and both Drift Resolution branches rather than a generic toggle. - Confirmation tests cover safe default focus, cancellation without mutation, Profile deletion, Docker restart, and confirmation required during Active Profile switching. - Accessibility tests verify that state, focus, progress, warnings, and errors remain understandable with color disabled. - Credential tests inject secrets through Profile fields, malformed URLs, evidence, notices, errors, runner output, and confirmation text, then assert that no rendered frame contains the secret. - Startup tests assert immediate dashboard rendering followed by independent Target detection updates rather than waiting for one aggregate completion. - Busy-state tests assert that browsing remains available, conflicting mutations are disabled, and exit is visibly deferred until safe completion. - Full repository tests remain hermetic and must not mutate real Shell, APT, Docker, GNOME, or systemd state. ## Out of Scope - Mouse input, clickable controls, hover states, or wheel-specific interaction. - Nerd Font or terminal-font installation requirements. - User-selectable theme packs or a theme configuration screen. - Large ASCII logos or decorative animation unrelated to progress. - An in-TUI activity or historical log viewer. - Automatic proxy connectivity tests, latency checks, health monitoring, or background network requests. - Treating Enabled Target state as proof that the proxy endpoint or Internet is reachable. - Changes to Profile persistence format unless independently required by a later specification. - Reworking stable Target-specific proxy translation, file ownership, restoration, permission, or service-control behavior. - Cross-Target rollback after partial Active Profile transition failure. - Parallel system mutations. - Long-term coexistence of legacy and redesigned TUI implementations. - Changes to doctor, reset, Shell integration, release packaging, or non-interactive CLI behavior except where shared Application Interface evolution requires compatibility adaptation. - A graphical desktop interface or web interface. ## Further Notes - The project glossary defines Drift Resolution as the explicit choice between reapplying the Active Profile and restoring original configuration when ownership evidence permits. UI copy and Application intents should use this language consistently. - The throwaway interactive prototype selected **Variant A — Operations Console**: a compact responsive Target list and details layout. Wide terminals use side-by-side panes; narrow terminals stack the same regions vertically. This won over the metric-heavy status board and the single-Target workbench because it preserves complete Target scanability while keeping evidence and actions visible. - The full three-variant prototype is preserved as the primary design source on branch `prototype/tui-operations-console` at commit `364f28d`. Its prototype code must not be promoted directly into production. - The redesign should retain the product's privacy boundary: Protocol Probe is the only user-initiated network handshake, and display of its result must not imply general connectivity.