From bec3da3d31a2e6ac3b56195fcb27fd6749dd8326 Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Sun, 9 Aug 2026 04:06:24 +0200 Subject: [PATCH] fix(ui): a described session tab shows just the description (#232) Reported by @mtiller. A session named `w2-foo-bar: some description` rendered both halves on the tab, so the generated id ate the width that the part the user actually chose needed. The tab now shows the description alone and the `w-` id moves to the tooltip, where it stays available without being read every time. It is still shown in the session settings modal. Undescribed tabs are unchanged. `aria-label` deliberately keeps the FULL name, so screen readers still get the id. Also fixes a re-render loop this exposed: the incremental update compared `nameEl.textContent` against the full name, which for a described tab never matched, so those tabs re-rendered on every pass. The compare now targets the display label. Co-Authored-By: Claude Opus 5 (1M context) --- src/web/public/app.js | 30 ++++++++++++++++++++++-------- src/web/public/styles.css | 9 --------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/web/public/app.js b/src/web/public/app.js index a61c9217..157fc392 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -3438,14 +3438,19 @@ class CodemanApp { statusEl.className = `tab-status ${status}`; } - // Update name if changed + // Update name if changed. #232: a description (the `: suffix` part of the + // name) is the whole tab label; the generated id lives in the tooltip. The + // compare targets the DISPLAY text, or a described tab would re-render on + // every pass (textContent never equals the full name there). const nameEl = tab.querySelector('.tab-name'); - if (nameEl && nameEl.textContent !== name) { + if (nameEl) { const _p = parseSessionPrefix(name); - if (_p && _p.suffix) { - nameEl.innerHTML = '' + escapeHtml(_p.prefix) + ': ' + escapeHtml(_p.suffix) + ''; - } else { - nameEl.textContent = name; + const _label = _p && _p.suffix ? _p.suffix : name; + if (nameEl.textContent !== _label) { + nameEl.textContent = _label; + tab.title = _p && _p.suffix + ? (session.workingDir ? `${_p.prefix} (${session.workingDir})` : _p.prefix) + : (session.workingDir || ''); } } @@ -3617,14 +3622,23 @@ class CodemanApp { const tallTabsEnabled = this._tallTabsEnabled ?? false; const showFolder = tallTabsEnabled && session.name && folderName && folderName !== name; - parts.push(`