diff --git a/api/config.py b/api/config.py index 8ef8bbf..8d1691b 100644 --- a/api/config.py +++ b/api/config.py @@ -633,6 +633,7 @@ _SETTINGS_DEFAULTS = { 'default_workspace': str(DEFAULT_WORKSPACE), 'send_key': 'enter', # 'enter' or 'ctrl+enter' 'show_token_usage': False, # show input/output token badge below assistant messages + 'show_cli_sessions': False, # merge CLI sessions from state.db into the sidebar 'password_hash': None, # SHA-256 hash; None = auth disabled } @@ -652,7 +653,7 @@ _SETTINGS_ALLOWED_KEYS = set(_SETTINGS_DEFAULTS.keys()) - {'password_hash'} _SETTINGS_ENUM_VALUES = { 'send_key': {'enter', 'ctrl+enter'}, } -_SETTINGS_BOOL_KEYS = {'show_token_usage'} +_SETTINGS_BOOL_KEYS = {'show_token_usage', 'show_cli_sessions'} def save_settings(settings: dict) -> dict: """Save settings to disk. Returns the merged settings. Ignores unknown keys.""" diff --git a/api/routes.py b/api/routes.py index 8b73115..2c0fc01 100644 --- a/api/routes.py +++ b/api/routes.py @@ -188,10 +188,13 @@ def handle_get(handler, parsed): if parsed.path == '/api/sessions': webui_sessions = all_sessions() - cli = get_cli_sessions() - # Deduplicate: WebUI sessions always win if same session_id - webui_ids = {s['session_id'] for s in webui_sessions} - deduped_cli = [s for s in cli if s['session_id'] not in webui_ids] + settings = load_settings() + if settings.get('show_cli_sessions'): + cli = get_cli_sessions() + webui_ids = {s['session_id'] for s in webui_sessions} + deduped_cli = [s for s in cli if s['session_id'] not in webui_ids] + else: + deduped_cli = [] merged = webui_sessions + deduped_cli merged.sort(key=lambda s: s.get('updated_at', 0) or 0, reverse=True) return j(handler, {'sessions': merged, 'cli_count': len(deduped_cli)}) diff --git a/static/boot.js b/static/boot.js index 9aab685..43e6a20 100644 --- a/static/boot.js +++ b/static/boot.js @@ -308,7 +308,7 @@ document.querySelectorAll('.suggestion').forEach(btn=>{ (async()=>{ // Load send key preference - try{const s=await api('/api/settings');window._sendKey=s.send_key||'enter';window._showTokenUsage=!!s.show_token_usage;}catch(e){window._sendKey='enter';window._showTokenUsage=false;} + try{const s=await api('/api/settings');window._sendKey=s.send_key||'enter';window._showTokenUsage=!!s.show_token_usage;window._showCliSessions=!!s.show_cli_sessions;}catch(e){window._sendKey='enter';window._showTokenUsage=false;window._showCliSessions=false;} // Fetch active profile try{const p=await api('/api/profile/active');S.activeProfile=p.name||'default';}catch(e){S.activeProfile='default';} // Update profile chip label immediately diff --git a/static/index.html b/static/index.html index 93e40e4..ff36311 100644 --- a/static/index.html +++ b/static/index.html @@ -331,6 +331,13 @@
Displays input/output token count below each assistant reply. Also toggled with /usage.
+
+ +
Merges sessions from the Hermes CLI (state.db) into the session list. Click a CLI session to import it and continue the conversation.
+
Enter a new password to set or change it. Leave blank to keep current setting.
diff --git a/static/panels.js b/static/panels.js index eab2d5d..043d6f1 100644 --- a/static/panels.js +++ b/static/panels.js @@ -960,6 +960,8 @@ async function loadSettingsPanel(){ if(sendKeySel) sendKeySel.value=settings.send_key||'enter'; const showUsageCb=$('settingsShowTokenUsage'); if(showUsageCb) showUsageCb.checked=!!settings.show_token_usage; + const showCliCb=$('settingsShowCliSessions'); + if(showCliCb) showCliCb.checked=!!settings.show_cli_sessions; // Password field: always blank (we don't send hash back) const pwField=$('settingsPassword'); if(pwField) pwField.value=''; @@ -982,12 +984,14 @@ async function saveSettings(){ const workspace=($('settingsWorkspace')||{}).value; const sendKey=($('settingsSendKey')||{}).value; const showTokenUsage=!!($('settingsShowTokenUsage')||{}).checked; + const showCliSessions=!!($('settingsShowCliSessions')||{}).checked; const pw=($('settingsPassword')||{}).value; const body={}; if(model) body.default_model=model; if(workspace) body.default_workspace=workspace; if(sendKey) body.send_key=sendKey; body.show_token_usage=showTokenUsage; + body.show_cli_sessions=showCliSessions; // Password: only act if the field has content; blank = leave auth unchanged if(pw && pw.trim()){ try{ @@ -1003,7 +1007,9 @@ async function saveSettings(){ await api('/api/settings',{method:'POST',body:JSON.stringify(body)}); window._sendKey=sendKey||'enter'; window._showTokenUsage=showTokenUsage; + window._showCliSessions=showCliSessions; renderMessages(); + if(typeof renderSessionList==='function') renderSessionList(); showToast('Settings saved'); toggleSettings(); }catch(e){