fix: apply_update concurrency lock, boot.js settings-fail guard, dead workspace code, test_updates URL param

- api/updates.py: add _apply_lock to prevent concurrent stash/pull/pop
- static/boot.js: set check_for_updates:false on settings fetch failure
- static/panels.js: remove dead settingsWorkspace references (element removed from HTML)
- api/routes.py + static/boot.js: add ?test_updates=1 URL param for testing banner
  without being behind on git (localhost-only simulate endpoint)
This commit is contained in:
Nathan Esquenazi
2026-04-05 16:20:12 +00:00
parent 8d1b7a1e01
commit beb56b1a8b
4 changed files with 27 additions and 21 deletions

View File

@@ -309,10 +309,13 @@ document.querySelectorAll('.suggestion').forEach(btn=>{
(async()=>{
// Load send key preference
let _bootSettings={};
try{const s=await api('/api/settings');_bootSettings=s;window._sendKey=s.send_key||'enter';window._showTokenUsage=!!s.show_token_usage;window._showCliSessions=!!s.show_cli_sessions;const _theme=s.theme||'dark';document.documentElement.dataset.theme=_theme;localStorage.setItem('hermes-theme',_theme);}catch(e){window._sendKey='enter';window._showTokenUsage=false;window._showCliSessions=false;}
try{const s=await api('/api/settings');_bootSettings=s;window._sendKey=s.send_key||'enter';window._showTokenUsage=!!s.show_token_usage;window._showCliSessions=!!s.show_cli_sessions;const _theme=s.theme||'dark';document.documentElement.dataset.theme=_theme;localStorage.setItem('hermes-theme',_theme);}catch(e){window._sendKey='enter';window._showTokenUsage=false;window._showCliSessions=false;_bootSettings={check_for_updates:false};}
// Non-blocking update check (fire-and-forget, once per tab session)
if(_bootSettings.check_for_updates!==false&&!sessionStorage.getItem('hermes-update-checked')&&!sessionStorage.getItem('hermes-update-dismissed')){
api('/api/updates/check').then(d=>{sessionStorage.setItem('hermes-update-checked','1');if((d.webui&&d.webui.behind>0)||(d.agent&&d.agent.behind>0))_showUpdateBanner(d);}).catch(()=>{});
// ?test_updates=1 in URL forces banner display for testing (bypasses sessionStorage guards)
const _testUpdates=new URLSearchParams(location.search).get('test_updates')==='1';
if(_testUpdates||(_bootSettings.check_for_updates!==false&&!sessionStorage.getItem('hermes-update-checked')&&!sessionStorage.getItem('hermes-update-dismissed'))){
const _checkUrl='/api/updates/check'+(_testUpdates?'?simulate=1':'');
api(_checkUrl).then(d=>{if(!_testUpdates)sessionStorage.setItem('hermes-update-checked','1');if((d.webui&&d.webui.behind>0)||(d.agent&&d.agent.behind>0))_showUpdateBanner(d);}).catch(()=>{});
}
// Fetch active profile
try{const p=await api('/api/profile/active');S.activeProfile=p.name||'default';}catch(e){S.activeProfile='default';}

View File

@@ -995,21 +995,6 @@ async function loadSettingsPanel(){
modelSel.value=settings.default_model||'';
modelSel.addEventListener('change',_markSettingsDirty,{once:false});
}
// Populate workspace dropdown from /api/workspaces
const wsSel=$('settingsWorkspace');
if(wsSel){
wsSel.innerHTML='';
try{
const wsData=await api('/api/workspaces');
for(const w of (wsData.workspaces||[])){
const opt=document.createElement('option');
opt.value=w.path;opt.textContent=w.name||w.path;
wsSel.appendChild(opt);
}
}catch(e){}
wsSel.value=settings.default_workspace||'';
wsSel.addEventListener('change',_markSettingsDirty,{once:false});
}
// Send key preference
const sendKeySel=$('settingsSendKey');
if(sendKeySel){sendKeySel.value=settings.send_key||'enter';sendKeySel.addEventListener('change',_markSettingsDirty,{once:false});}
@@ -1043,7 +1028,6 @@ async function loadSettingsPanel(){
async function saveSettings(andClose){
const model=($('settingsModel')||{}).value;
const workspace=($('settingsWorkspace')||{}).value;
const sendKey=($('settingsSendKey')||{}).value;
const showTokenUsage=!!($('settingsShowTokenUsage')||{}).checked;
const showCliSessions=!!($('settingsShowCliSessions')||{}).checked;
@@ -1051,7 +1035,7 @@ async function saveSettings(andClose){
const theme=($('settingsTheme')||{}).value||'dark';
const body={};
if(model) body.default_model=model;
if(workspace) body.default_workspace=workspace;
if(sendKey) body.send_key=sendKey;
body.theme=theme;
body.show_token_usage=showTokenUsage;