From 0c17409fb15d44ee78683f5078c9b453acdc1c54 Mon Sep 17 00:00:00 2001 From: Nattapong Tapachoom Date: Wed, 28 Jan 2026 09:34:57 +0700 Subject: [PATCH] feat(security): add logout button to Control UI and /logout command to TUI - Control UI: Added logout button in topbar that clears stored credentials (token/password) from localStorage - TUI: Added /logout command that disconnects from gateway and exits securely - Added clearCredentials() function in storage.ts for credential cleanup - Security improvement: Users can now explicitly revoke stored authentication [AI-assisted] --- src/tui/commands.ts | 2 + src/tui/tui-command-handlers.ts | 8 + ui/src/ui/app-render.helpers.ts | 93 +++- ui/src/ui/app-render.ts | 811 +++++++++++++++++--------------- ui/src/ui/app-view-state.ts | 6 +- ui/src/ui/app.ts | 121 ++--- ui/src/ui/storage.ts | 42 +- 7 files changed, 594 insertions(+), 489 deletions(-) diff --git a/src/tui/commands.ts b/src/tui/commands.ts index dfc419632..cc0f01c82 100644 --- a/src/tui/commands.ts +++ b/src/tui/commands.ts @@ -115,6 +115,7 @@ export function getSlashCommands(options: SlashCommandOptions = {}): SlashComman { name: "new", description: "Reset the session" }, { name: "reset", description: "Reset the session" }, { name: "settings", description: "Open settings" }, + { name: "logout", description: "Disconnect and exit securely" }, { name: "exit", description: "Exit the TUI" }, { name: "quit", description: "Exit the TUI" }, ]; @@ -154,6 +155,7 @@ export function helpText(options: SlashCommandOptions = {}): string { "/new or /reset", "/abort", "/settings", + "/logout", "/exit", ].join("\n"); } diff --git a/src/tui/tui-command-handlers.ts b/src/tui/tui-command-handlers.ts index a14172809..1fc9f92e6 100644 --- a/src/tui/tui-command-handlers.ts +++ b/src/tui/tui-command-handlers.ts @@ -427,6 +427,14 @@ export function createCommandHandlers(context: CommandHandlerContext) { case "settings": openSettings(); break; + case "logout": + chatLog.addSystem("Logging out... Disconnecting from gateway."); + tui.requestRender(); + client.stop(); + tui.stop(); + console.log("\nLogged out successfully."); + process.exit(0); + break; case "exit": case "quit": client.stop(); diff --git a/ui/src/ui/app-render.helpers.ts b/ui/src/ui/app-render.helpers.ts index 22f8d90db..ca7852f9c 100644 --- a/ui/src/ui/app-render.helpers.ts +++ b/ui/src/ui/app-render.helpers.ts @@ -32,7 +32,9 @@ export function renderTab(state: AppViewState, tab: Tab) { }} title=${titleForTab(tab)} > - + ${titleForTab(tab)} `; @@ -45,8 +47,39 @@ export function renderChatControls(state: AppViewState) { const showThinking = state.onboarding ? false : state.settings.chatShowThinking; const focusActive = state.onboarding ? true : state.settings.chatFocusMode; // Refresh icon - const refreshIcon = html``; - const focusIcon = html``; + const refreshIcon = html` + + + + + `; + const focusIcon = html` + + + + + + + + `; return html`