7.4 KiB
Chat Sidebar + Tabbed Layout
Goal
Redesign the agent chat UI for two use cases:
- Tabbed chat page — Split the current cluttered
sovereign://agents/chatpage into 3 tabs: Chat, Conversations, Skills. - Sidebar mode — Show the chat in a narrow left-hand sidebar alongside a web page on the right, so the user can chat about the page they're viewing.
Current state
The sovereign://agents/chat page has a two-pane layout:
- Left pane: conversation list + skills list (cluttered)
- Right pane: chat messages + input
This is too much for a sidebar. The user wants tabs to organize it.
Design
Tabbed chat page
┌─────────────────────────────────────────────────┐
│ [Chat] [Conversations] [Skills] │ ← tab bar
├─────────────────────────────────────────────────┤
│ │
│ (active tab content) │
│ │
└─────────────────────────────────────────────────┘
Tab 1: Chat (default)
- Chat messages (scrollable)
- Status messages (system bubbles)
- Input area (composer + send + stop)
Tab 2: Conversations
- "+ New Chat" button
- "↻ Refresh" button
- Conversation list (click to load, rename, delete)
Tab 3: Skills
- "↻ Refresh" button
- "+ Create Skill" button
- Skills list (checkboxes, edit, delete)
- Skill editor (inline, expandable)
When a conversation is selected in Tab 2, switch to Tab 1 automatically. When a skill is toggled in Tab 3, stay on Tab 3.
Sidebar mode
The sidebar is a narrow version of the chat page, shown alongside a web page. There are two approaches:
Option A — Split view in the same tab: The browser window splits into
two webviews: a narrow left webview showing sovereign://agents/chat (in
sidebar mode), and a right webview showing the web page. This requires
GTK-level changes to tab_manager.c to support split views.
Option B — Separate sidebar panel: A GTK panel (like a GtkPaned or GtkBox) on the left side of the browser window, showing the chat UI natively (not as a webview). This is more work but gives a native feel.
Option C — Pop-out sidebar tab: The chat page detects when it's loaded in a narrow viewport and switches to a compact sidebar layout (tabs become icons, messages take full width). This is the simplest — no GTK changes, just CSS responsive design.
I recommend Option A (split view) for the first implementation — it reuses the existing chat page in a narrow webview, and the tabbed layout makes it work well in a narrow space.
Split view implementation (Option A)
┌──────────────────────────────────────────────────────────┐
│ [tab strip] │
├─────────────────┬────────────────────────────────────────┤
│ [Chat][Conv] │ │
│ [Skills] │ │
│ │ Web page (right webview) │
│ Chat messages │ │
│ ... │ │
│ │ │
│ [input area] │ │
└─────────────────┴────────────────────────────────────────┘
← sidebar (300px) ← web page (flex: 1)
The sidebar is a second webview in the same tab, showing
sovereign://agents/chat in a compact layout. The user can toggle the
sidebar on/off via a menu item or keyboard shortcut.
Implementation
Phase 1 — Tabbed chat page
-
www/agents/chat.html— Restructure into 3 tabs:<div id="tab-bar"> <button class="tab active" data-tab="chat">Chat</button> <button class="tab" data-tab="conversations">Conversations</button> <button class="tab" data-tab="skills">Skills</button> </div> <div id="tab-chat" class="tab-content active"> <!-- messages + status + input --> </div> <div id="tab-conversations" class="tab-content"> <!-- new chat, refresh, conversation list --> </div> <div id="tab-skills" class="tab-content"> <!-- refresh, create skill, skills list --> </div> -
www/agents/chat.css— Tab bar styling (horizontal buttons, active state), tab content (only active tab visible). -
www/agents/chat.js— Tab switching logic:switchTab(name)— hides all tab contents, shows the selected one, updates the active class on the tab buttons.loadConv()— after loading a conversation, switch to the "chat" tab.newChat()— after creating a new chat, switch to the "chat" tab.
Phase 2 — Sidebar mode (split view)
-
src/tab_manager.c— Add a sidebar webview to each tab:- Each
tab_info_tgets asidebar_webviewfield. - The tab's container becomes a
GtkPaned(horizontal) with the sidebar on the left and the main webview on the right. - The sidebar webview loads
sovereign://agents/chatwhen shown. - A menu item "Toggle Agent Sidebar" (or keyboard shortcut) shows/hides the sidebar.
- Each
-
src/tab_manager.h— Addsidebar_webviewtotab_info_t. -
www/agents/chat.css— Responsive layout: when the viewport is narrow (< 400px), switch to a compact layout (tab bar becomes icons, messages take full width, smaller fonts). -
src/main.c— Add a menu item "Toggle Agent Sidebar" and keyboard shortcut (e.g., Ctrl+Shift+A).
Phase 3 — Sidebar-aware behavior
-
Agent tools target the main webview — When the agent calls browser tools (snapshot, click, eval), they should operate on the main webview (the web page), not the sidebar webview (the chat page). Update
agent_tools.cto use the main webview, not the active webview. -
URL bar
;shortcut — When the user types; <message>in the URL bar, if the sidebar is open, send the message to the sidebar's chat. If not, open the sidebar and send the message.
Files to modify
| File | Change |
|---|---|
www/agents/chat.html |
Restructure into 3 tabs |
www/agents/chat.css |
Tab bar styling, responsive sidebar layout |
www/agents/chat.js |
Tab switching logic, sidebar-aware behavior |
src/tab_manager.c |
Add sidebar webview, GtkPaned split, toggle |
src/tab_manager.h |
Add sidebar_webview to tab_info_t |
src/main.c |
Add "Toggle Agent Sidebar" menu item + shortcut |
src/agent_tools.c |
Browser tools target main webview, not sidebar |
Phasing
Phase 1: Tabbed chat page (HTML/CSS/JS only, no C changes). Phase 2: Sidebar mode (split view, GTK changes). Phase 3: Sidebar-aware behavior (agent tools target main webview).