diff --git a/frontend/packages/agent/src/app.js b/frontend/packages/agent/src/app.js index 190e3cc1..09fa5d70 100644 --- a/frontend/packages/agent/src/app.js +++ b/frontend/packages/agent/src/app.js @@ -1926,13 +1926,19 @@ window.marked = marked; // tick starts a fresh row. if (v.subtype === 'thinking_tokens') { const n = v.estimated_tokens; - const label = '🧠 thinking … ' + const text = 'thinking … ' + (n != null ? '~' + Number(n).toLocaleString() + ' tokens' : ''); if (thinkingTokensRow && thinkingTokensRow.isConnected && thinkingTokensRow.nextElementSibling === null) { - thinkingTokensRow.textContent = label; + // Update only the text portion after the icon glyph + // (textContent would clobber the .row-glyph span). + const glyph = thinkingTokensRow.querySelector('.row-glyph'); + [...thinkingTokensRow.childNodes].forEach((node) => { + if (node !== glyph) thinkingTokensRow.removeChild(node); + }); + thinkingTokensRow.appendChild(document.createTextNode(text)); } else { - thinkingTokensRow = api.row('note', label); + thinkingTokensRow = api.row('note', text, '🧠'); } return; } diff --git a/frontend/packages/shared/src/terminal.css b/frontend/packages/shared/src/terminal.css index 01d4a906..2abc36f8 100644 --- a/frontend/packages/shared/src/terminal.css +++ b/frontend/packages/shared/src/terminal.css @@ -216,11 +216,44 @@ details.row { white-space: normal; } +/* Two-column layout for expandable summary rows. + Left col: fixed-width icon cell. Right col: disclosure chevron + + text, wrapping within itself so no continuation line bleeds under + the icon. Overrides the flat-row hanging-indent metrics (.live .row + sets padding-left: 1.9em; text-indent: -1.4em) with explicit flex + geometry. The negative margin-left on summary cancels the details + container's inherited padding-left so the icon lands at the same + horizontal position as flat-row icons. */ details.row > summary { cursor: pointer; list-style: none; white-space: pre-wrap; word-break: break-word; + display: flex; + align-items: baseline; + margin-left: -1.9em; + padding-left: 0.5em; + text-indent: 0; +} +/* Icon column: 2em accommodates wide emoji without ink bleeding into + the chevron column. Overrides the inline-block + width: 1.4em set + on .live .row-glyph for the shared flat-row context. */ +details.row > summary > .row-glyph { + flex: 0 0 2em; + width: auto; + text-align: center; +} +/* Content column: chevron (::before) + text, wraps within the cell. */ +details.row > summary > .summary-text { + flex: 1; + min-width: 0; +} +/* Icon-less summaries: the CSS-generated ▸/▾ acts as the hanging + marker. Hanging indent keeps wrapped lines under the text body, + not under the chevron. Mirrors the flat-row text-indent metric. */ +details.row > summary > .summary-text:only-child { + padding-left: 1.4em; + text-indent: -1.4em; } details.row > summary > .summary-text::before { content: '▸ ';