From d12b028c81977a752919c5cf1df0f9e54dc5c1c5 Mon Sep 17 00:00:00 2001 From: Michael Lam Date: Mon, 4 May 2026 16:58:54 -0700 Subject: [PATCH] feat: add WebUI status command card --- docs/pr-media/463/status-command-card.png | Bin 0 -> 59163 bytes static/commands.js | 88 +++++++++++++------- static/i18n.js | 23 +++++ static/style.css | 15 ++++ static/ui.js | 48 +++++++++-- tests/test_status_command_card.py | 97 ++++++++++++++++++++++ 6 files changed, 238 insertions(+), 33 deletions(-) create mode 100644 docs/pr-media/463/status-command-card.png create mode 100644 tests/test_status_command_card.py diff --git a/docs/pr-media/463/status-command-card.png b/docs/pr-media/463/status-command-card.png new file mode 100644 index 0000000000000000000000000000000000000000..ac63b7d7bd71f2af48711a1888e0d3961e03d58c GIT binary patch literal 59163 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 literal 0 HcmV?d00001 diff --git a/static/commands.js b/static/commands.js index 6dce4c48..90fc5aca 100644 --- a/static/commands.js +++ b/static/commands.js @@ -819,35 +819,67 @@ async function cmdBackground(args){ if(typeof startBackgroundPolling==='function') startBackgroundPolling(activeSid,r.task_id,prompt); }catch(e){showToast(t('bg_failed')+e.message);} } -async function cmdStatus(){ +function _formatStatusTimestamp(value){ + if(value===undefined||value===null||value==='') return t('status_unknown'); + let date; + if(typeof value==='number') date=new Date(value < 1000000000000 ? value*1000 : value); + else date=new Date(value); + if(Number.isNaN(date.getTime())) return t('status_unknown'); + return date.toLocaleString(); +} +function _formatStatusTokens(s){ + const lastUsage=(typeof S!=='undefined'&&(S.lastUsage||s.last_usage))||{}; + const input=Number(s.input_tokens??lastUsage.input_tokens??0)||0; + const output=Number(s.output_tokens??lastUsage.output_tokens??0)||0; + const total=Number(s.total_tokens??lastUsage.total_tokens??(input+output))||0; + const cost=Number(s.estimated_cost??lastUsage.estimated_cost??0)||0; + if(!total&&!cost) return t('status_no_tokens'); + const fmtNum=n=>Number(n||0).toLocaleString(); + return `${fmtNum(input)} in / ${fmtNum(output)} out${cost?` (~$${cost.toFixed(4)})`:''}`; +} +function _statusProviderForSession(s){ + if(s.model_provider) return String(s.model_provider); + if(window._activeProvider) return String(window._activeProvider); + const model=String(s.model||''); + return model.includes('/') ? model.split('/')[0] : ''; +} +function _statusCardFromSession(s){ + const provider=_statusProviderForSession(s); + const model=s.model||(($('modelSelect')&&$('modelSelect').value)||t('usage_default_model')); + const running=!!(s.active_stream_id||S.activeStreamId||S.busy); + const profile=s.profile||S.activeProfile||'default'; + const workspace=s.workspace||S.currentDir||t('status_unknown'); + const rows=[ + {label:t('status_session_id'), value:s.session_id||t('status_unknown')}, + {label:t('status_title'), value:s.title||t('untitled')}, + {label:t('status_model'), value:model}, + {label:t('status_provider'), value:provider||t('status_unknown')}, + {label:t('status_profile'), value:profile}, + {label:t('status_workspace'), value:workspace}, + {label:t('status_personality'), value:s.personality||t('usage_personality_none')}, + {label:t('status_started'), value:_formatStatusTimestamp(s.created_at)}, + {label:t('status_updated'), value:_formatStatusTimestamp(s.updated_at||s.last_message_at)}, + {label:t('status_tokens'), value:_formatStatusTokens(s)}, + {label:t('status_messages'), value:String(s.message_count??(S.messages||[]).filter(m=>m&&m.role&&m.role!=='tool').length)}, + {label:t('status_agent_running'), value:running?t('status_yes'):t('status_no')}, + ]; + return { + title:t('status_heading'), + subtitle:t('status_ephemeral'), + sessionId:s.session_id||'', + rows, + }; +} +function cmdStatus(){ if(!S.session){showToast(t('no_active_session'));return;} - try{ - const r=await api('/api/session/status?session_id='+encodeURIComponent(S.session.session_id)); - if(r&&r.error){showToast(r.error);return;} - // Build status card lines matching CLI /status output - const provider=window._activeProvider||''; - const profile=r.profile||S.activeProfile||'default'; - const started=r.created_at?new Date(r.created_at).toLocaleString():t('status_unknown'); - const fmtNum=n=>typeof n==='number'?n.toLocaleString():'0'; - const tokens=r.total_tokens?`${fmtNum(r.input_tokens)} in / ${fmtNum(r.output_tokens)} out`:t('status_no_tokens'); - const cost=r.estimated_cost?` (~$${Number(r.estimated_cost).toFixed(4)})`:''; - const lines=[ - `**${t('status_heading')}**`,'', - `\`${r.session_id}\``,'', - `**${t('status_title')}:** ${r.title||t('untitled')}`, - `**${t('status_model')}:** ${r.model||t('usage_default_model')}${provider?' ('+provider+')':''}`, - `**${t('status_profile')}:** ${profile}`, - `**${t('status_hermes_home')}:** ${r.hermes_home||t('status_unknown')}`, - `**${t('status_workspace')}:** ${r.workspace}`, - `**${t('status_personality')}:** ${r.personality||t('usage_personality_none')}`, - `**${t('status_started')}:** ${started}`, - `**${t('status_tokens')}:** ${tokens}${cost}`, - `**${t('status_messages')}:** ${r.message_count}`, - `**${t('status_agent_running')}:** ${r.agent_running?t('status_yes'):t('status_no')}`, - ]; - S.messages.push({role:'assistant',content:lines.join('\n')}); - renderMessages(); - }catch(e){showToast(t('status_load_failed')+e.message);} + S.messages.push({ + role:'assistant', + content:'', + _ephemeral:true, + _statusCard:_statusCardFromSession(S.session), + _ts:Date.now()/1000, + }); + renderMessages(); } function cmdReasoning(args){ const arg=(args||'').trim().toLowerCase(); diff --git a/static/i18n.js b/static/i18n.js index 94625d78..1cc86b7e 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -225,6 +225,7 @@ const LOCALES = { status_session_id:'Session ID', status_title:'Title', status_model:'Model', + status_provider:'Provider', status_workspace:'Workspace', status_personality:'Personality', status_messages:'Messages', @@ -232,7 +233,9 @@ const LOCALES = { status_profile: 'Profile', status_hermes_home: 'Hermes home', status_started: 'Started', + status_updated: 'Updated', status_tokens: 'Tokens', + status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No tokens used', status_unknown: 'Unknown', status_yes:'Yes', @@ -1185,6 +1188,7 @@ const LOCALES = { status_session_id:'セッションID', status_title:'タイトル', status_model:'モデル', + status_provider:'プロバイダー', status_workspace:'ワークスペース', status_personality:'パーソナリティ', status_messages:'メッセージ', @@ -1193,6 +1197,8 @@ const LOCALES = { status_hermes_home: 'Hermes ホーム', status_started: '開始', status_tokens: 'トークン', + status_updated: '更新', + status_ephemeral: '一時的なスナップショット — 履歴には保存されません。', status_no_tokens: 'トークン未使用', status_unknown: '不明', status_yes:'はい', @@ -2714,6 +2720,8 @@ const LOCALES = { settings_tab_conversation: 'Conversation', settings_tab_preferences: 'Preferences', settings_tab_system: 'System', + status_updated: 'Updated', + status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No token data', status_profile: 'Profile', status_hermes_home: 'Hermes home', @@ -3598,6 +3606,8 @@ const LOCALES = { settings_tab_conversation: 'Conversation', settings_tab_preferences: 'Preferences', settings_tab_system: 'System', + status_updated: 'Updated', + status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No token data', status_profile: 'Profile', status_hermes_home: 'Hermes home', @@ -4229,6 +4239,8 @@ const LOCALES = { settings_tab_conversation: 'Conversation', settings_tab_preferences: 'Preferences', settings_tab_system: 'System', + status_updated: 'Updated', + status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No token data', status_profile: 'Profile', status_hermes_home: 'Hermes home', @@ -5387,6 +5399,8 @@ const LOCALES = { settings_tab_conversation: 'Conversation', settings_tab_preferences: 'Preferences', settings_tab_system: 'System', + status_updated: 'Updated', + status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No token data', status_profile: 'Profile', status_hermes_home: 'Hermes home', @@ -6253,6 +6267,8 @@ const LOCALES = { status_hermes_home: 'Hermes 主目錄', status_started: '開始時間', status_tokens: 'Token', + status_updated: '已更新', + status_ephemeral: '临时快照 — 不会保存到对话历史。', status_no_tokens: '未使用 Token', status_unknown: '未知', status_completed: '\u5df2\u5b8c\u6210', @@ -6261,6 +6277,7 @@ const LOCALES = { status_load_failed: '\u8f09\u5165\u72c0\u614b\u5931\u6557\uff1a', status_messages: '\u8a0a\u606f\u6578', status_model: '\u6a21\u578b', + status_provider: '供应商', status_no: '\u5426', status_personality: '\u4eba\u8a2d', status_session_id: '\u6703\u8a71 ID', @@ -6626,6 +6643,7 @@ const LOCALES = { status_session_id: 'ID da Sessão', status_title: 'Título', status_model: 'Modelo', + status_provider: 'Provedor', status_workspace: 'Workspace', status_personality: 'Personalidade', status_messages: 'Mensagens', @@ -6634,6 +6652,8 @@ const LOCALES = { status_hermes_home: 'Diretório Hermes', status_started: 'Iniciado', status_tokens: 'Tokens', + status_updated: 'Atualizado', + status_ephemeral: 'Instantâneo efêmero — não salvo no histórico.', status_no_tokens: 'Nenhum token usado', status_unknown: 'Desconhecido', status_yes: 'Sim', @@ -7464,6 +7484,7 @@ const LOCALES = { status_session_id: '세션 ID', status_title: '제목', status_model: '모델', + status_provider: '제공자', status_workspace: '워크스페이스', status_personality: '페르소나', status_messages: '메시지', @@ -7472,6 +7493,8 @@ const LOCALES = { status_hermes_home: 'Hermes 홈', status_started: '시작 시간', status_tokens: '토큰', + status_updated: '업데이트됨', + status_ephemeral: '임시 스냅샷 — 대화 기록에 저장되지 않습니다.', status_no_tokens: '사용된 토큰 없음', status_unknown: '알 수 없음', status_yes: '예', diff --git a/static/style.css b/static/style.css index fe5cbcee..3afd56bd 100644 --- a/static/style.css +++ b/static/style.css @@ -2637,6 +2637,21 @@ main.main.showing-profiles > #mainProfiles{display:flex;} .msg-body:empty { display: none; } .assistant-turn { width: 100%; } .assistant-turn-blocks { display: flex; flex-direction: column; } +.status-card{margin:8px 0 8px var(--msg-rail);max-width:min(var(--msg-max),760px);border:1px solid var(--border-subtle);background:var(--surface-subtle);border-radius:var(--radius-card);box-shadow:0 10px 24px rgba(0,0,0,.05);overflow:hidden;} +.status-card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:14px 16px;border-bottom:1px solid var(--border-subtle);background:linear-gradient(180deg,var(--surface-subtle-hover),var(--surface-subtle));} +.status-card-title-wrap{min-width:0;} +.status-card-title{font-weight:650;color:var(--text);font-size:14px;letter-spacing:.01em;} +.status-card-subtitle{font-size:12px;color:var(--muted);margin-top:3px;} +.status-card-session-copy{display:inline-flex;align-items:center;gap:7px;min-height:28px;padding:5px 9px;border:1px solid var(--border-subtle);border-radius:999px;background:var(--surface);color:var(--muted);font-size:12px;font-family:var(--font-mono);cursor:pointer;max-width:230px;} +.status-card-session-copy span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;} +.status-card-session-copy:hover,.status-card-session-copy.copied{color:var(--accent-text);border-color:var(--accent-bg-strong);background:var(--accent-bg);} +.status-card-grid{display:grid;grid-template-columns:minmax(120px,180px) minmax(0,1fr);gap:0;border-top:0;} +.status-card-row{display:contents;} +.status-card-label,.status-card-value{padding:9px 16px;border-top:1px solid var(--border-subtle);font-size:13px;line-height:1.4;} +.status-card-row:first-child .status-card-label,.status-card-row:first-child .status-card-value{border-top:0;} +.status-card-label{color:var(--muted);font-weight:550;background:rgba(0,0,0,.015);} +.status-card-value{color:var(--text);word-break:break-word;font-family:var(--font-mono);} +@media (max-width:700px){.status-card{margin-left:0;}.status-card-head{flex-direction:column;}.status-card-session-copy{max-width:100%;}.status-card-grid{grid-template-columns:1fr;}.status-card-label{padding-bottom:2px;border-top:1px solid var(--border-subtle);}.status-card-value{padding-top:2px;border-top:0;}} .assistant-segment-anchor { display: none; } /* ── Classic conversation layout: user right, half-width; assistant left ── */ diff --git a/static/ui.js b/static/ui.js index c45ab3da..53f21620 100644 --- a/static/ui.js +++ b/static/ui.js @@ -50,7 +50,6 @@ function _setCompressionSessionLock(sid){ window._compressionLockSid=sid||null; } const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); - /** * Render fenced code blocks inside user messages. * Extracts ```…``` fences, replaces them with placeholders, @@ -58,6 +57,7 @@ const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'& * with the same
 pipeline used by renderMd().
  * All non-fenced text stays escaped (no bold/italic/link interpretation).
  */
+
 function _renderUserFencedBlocks(text){
   const stash=[];
   let s=String(text||'');
@@ -89,6 +89,31 @@ function _renderUserFencedBlocks(text){
   s=s.replace(/\x00UF(\d+)\x00/g,(_,i)=>stash[+i]);
   return s;
 }
+function _statusCardHtml(card){
+  card=card||{};
+  const rows=Array.isArray(card.rows)?card.rows:[];
+  const sessionId=String(card.sessionId||'');
+  const shortSessionId=sessionId.length>22?`${sessionId.slice(0,10)}…${sessionId.slice(-8)}`:sessionId;
+  const copyIcon=(typeof li==='function')?li('copy',13):'Copy';
+  const copyBtn=sessionId
+    ? ``
+    : '';
+  const rowHtml=rows.map(row=>`
+    
+ ${esc(row.label||'')} + ${esc(row.value||'')} +
`).join(''); + return `
+
+
+
${esc(card.title||t('status_heading'))}
+
${esc(card.subtitle||'')}
+
+ ${copyBtn} +
+
${rowHtml}
+
`; +} /* ── Image lightbox — click any .msg-media-img to enlarge ─────────────────── */ function _openImgLightbox(src, alt) { @@ -2668,6 +2693,16 @@ function _fallbackCopy(text){ finally{document.body.removeChild(ta);} }); } +function copyStatusSessionId(btn){ + const text=btn&&btn.getAttribute('data-copy-status-session'); + if(!text)return; + _copyText(text).then(()=>{ + const orig=btn.innerHTML; + btn.innerHTML=(typeof li==='function')?li('check',13):t('copied'); + btn.classList.add('copied'); + setTimeout(()=>{btn.innerHTML=orig;btn.classList.remove('copied');},1500); + }).catch(()=>showToast(t('copy_failed'))); +} function copyMsg(btn){ const row=btn.closest('[data-raw-text]'); const text=row?row.dataset.rawText:''; @@ -3712,7 +3747,7 @@ function renderMessages(){ const hasTu=Array.isArray(m.content)&&m.content.some(p=>p&&p.type==='tool_use'); if(hasTc||hasTu||_messageHasReasoningPayload(m)) return true; } - return msgContent(m)||m.attachments?.length; + return m._statusCard||msgContent(m)||m.attachments?.length; }); $('emptyState').style.display=(vis.length||preservedCompressionTaskMessages.length)?'none':''; inner.innerHTML=''; @@ -3740,7 +3775,7 @@ function renderMessages(){ if(_isPreservedCompressionTaskListMessage(m)){preservedCompressionRawIdxs.push(rawIdx);rawIdx++;continue;} const hasTc=Array.isArray(m.tool_calls)&&m.tool_calls.length>0; const hasTu=Array.isArray(m.content)&&m.content.some(p=>p&&p.type==='tool_use'); - if(msgContent(m)||m.attachments?.length||(m.role==='assistant'&&(hasTc||hasTu||_messageHasReasoningPayload(m)))) visWithIdx.push({m,rawIdx}); + if(msgContent(m)||m._statusCard||m.attachments?.length||(m.role==='assistant'&&(hasTc||hasTu||_messageHasReasoningPayload(m)))) visWithIdx.push({m,rawIdx}); rawIdx++; } let lastUserRawIdx=-1; @@ -3821,6 +3856,7 @@ function renderMessages(){ }).join('')}`; } const bodyHtml = isUser ? _renderUserFencedBlocks(content) : renderMd(_stripXmlToolCallsDisplay(String(content))); + const statusHtml = (!isUser&&m._statusCard) ? _statusCardHtml(m._statusCard) : ''; const isEditableUser=isUser&&rawIdx===lastUserRawIdx; const editBtn = isEditableUser ? `` : ''; const undoBtn = isLastAssistant ? `` : ''; @@ -3886,8 +3922,10 @@ function renderMessages(){ if(isSimplifiedToolCalling()) assistantThinking.set(rawIdx, thinkingText); else if(window._showThinking!==false) seg.insertAdjacentHTML('beforeend', _thinkingCardHtml(thinkingText)); } - const hasVisibleBody=!!(String(content||'').trim()||filesHtml); - if(hasVisibleBody){ + const hasVisibleBody=!!(String(content||'').trim()||filesHtml||statusHtml); + if(statusHtml){ + seg.insertAdjacentHTML('beforeend', statusHtml); + }else if(hasVisibleBody){ seg.insertAdjacentHTML('beforeend', `${filesHtml}
${bodyHtml}
${footHtml}`); }else if(!(thinkingText&&window._showThinking!==false&&!isSimplifiedToolCalling())){ seg.classList.add('assistant-segment-anchor'); diff --git a/tests/test_status_command_card.py b/tests/test_status_command_card.py new file mode 100644 index 00000000..ca3fa44d --- /dev/null +++ b/tests/test_status_command_card.py @@ -0,0 +1,97 @@ +"""Regression tests for issue #463: WebUI /status info card. + +/status should be a client-handled slash command that renders a safe, +ephemeral assistant-style card from already-loaded session/profile/model data. +It must not round-trip through the agent or a status endpoint just to draw the +card. +""" +import pathlib + + +REPO_ROOT = pathlib.Path(__file__).parent.parent +COMMANDS_JS = (REPO_ROOT / "static" / "commands.js").read_text(encoding="utf-8") +UI_JS = (REPO_ROOT / "static" / "ui.js").read_text(encoding="utf-8") +STYLE_CSS = (REPO_ROOT / "static" / "style.css").read_text(encoding="utf-8") +I18N_JS = (REPO_ROOT / "static" / "i18n.js").read_text(encoding="utf-8") +MESSAGES_JS = (REPO_ROOT / "static" / "messages.js").read_text(encoding="utf-8") + + +def _function_body(src: str, name: str) -> str: + marker = f"function {name}" + start = src.index(marker) + brace = src.index("{", start) + depth = 0 + for idx in range(brace, len(src)): + if src[idx] == "{": + depth += 1 + elif src[idx] == "}": + depth -= 1 + if depth == 0: + return src[start:idx + 1] + raise AssertionError(f"Could not extract {name}()") + + +def test_status_command_is_registered_with_help_text(): + assert "{name:'status'" in COMMANDS_JS + assert "desc:t('cmd_status')" in COMMANDS_JS + assert "fn:cmdStatus" in COMMANDS_JS + assert "cmd_status:'Show session info'" in I18N_JS + + +def test_status_command_uses_client_state_not_status_endpoint(): + body = _function_body(COMMANDS_JS, "cmdStatus") + assert "/api/session/status" not in body + assert "api(" not in body + assert "S.session" in body + assert "S.activeProfile" in COMMANDS_JS + assert "model_provider" in COMMANDS_JS + assert "last_usage" in COMMANDS_JS + + +def test_status_command_pushes_ephemeral_status_card_message(): + body = _function_body(COMMANDS_JS, "cmdStatus") + assert "_statusCard" in body + assert "_ephemeral:true" in body + assert "renderMessages()" in body + assert "_statusCardFromSession(S.session)" in body + helper = _function_body(COMMANDS_JS, "_statusCardFromSession") + assert "session_id" in helper + assert "updated_at" in helper + assert "message_count" in helper + assert "active_stream_id" in helper + + +def test_status_card_renderer_escapes_all_dynamic_values_and_is_copyable(): + body = _function_body(UI_JS, "_statusCardHtml") + assert "data-status-card" in body + assert "data-copy-status-session" in body + assert "onclick=\"copyStatusSessionId(this);event.stopPropagation()\"" in body + assert "esc(card.title" in body + assert "esc(card.subtitle" in body + assert "esc(row.label" in body + assert "esc(row.value" in body + assert "esc(card.sessionId" in body + assert "renderMd(" not in body, "Status card data should not be interpreted as markdown" + + +def test_render_messages_treats_status_card_as_visible_assistant_content(): + render_body = _function_body(UI_JS, "renderMessages") + assert "m._statusCard" in render_body + assert "_statusCardHtml(m._statusCard)" in render_body + assert "statusHtml" in render_body + + +def test_status_card_styles_exist(): + assert ".status-card" in STYLE_CSS + assert ".status-card-grid" in STYLE_CSS + assert ".status-card-session-copy" in STYLE_CSS + + +def test_status_command_never_reaches_agent_send_path(): + send_body = _function_body(MESSAGES_JS, "send") + branch_start = send_body.index("if(text.startsWith('/')") + branch_end = send_body.index("if(_parsedCmd&&!_cmd)", branch_start) + cmd_branch = send_body[branch_start:branch_end] + assert "COMMANDS.find" in cmd_branch + assert "return;" in cmd_branch + assert "api('/api/chat/start'" not in cmd_branch