Skip to content

fix(agent-preset): make the truncated mode description reachable on hover - #455

Open
YeeBy2019 wants to merge 1 commit into
dataelement:mainfrom
YeeBy2019:fix-preset-description-truncation
Open

YeeBy2019 wants to merge 1 commit into
dataelement:mainfrom
YeeBy2019:fix-preset-description-truncation

Conversation

@YeeBy2019

Copy link
Copy Markdown

What

Two things in the agent-preset picker.

1. The ellipsised description had no way to be read. Every mode description is clipped
to a single line, and the row renders only <span class="itemDesc"> — no title, nothing
to hover. This picker is the one surface that prints a mode's own summary
(Two-tool coding agent with persistent bash and str_replace_editor,
Built for creating custom agent presets, with all Standard …), so the clipped tail was
simply lost. Rows keep their single line; the description span now carries a title, so
the full text is one hover away and the roster keeps the height it was laid out for.

2. The selected row's check sat away from its own text. Upstream's Menu.module.css
makes .itemLabel the flex child that absorbs the row's spare width:

.item      { display:flex; align-items:center; gap:8px; width:100%; }
.itemLabel { flex:1; min-width:0; }        /* ← absorbs the spare width */
.check     { flex:none; }

The trailing check follows whichever width that child ends up with, so a full-width label
strands the check in the leftover space instead of beside the text. The label is now told
to hug the row it labels (flex:0 1 auto), which puts the check back at the row's own 8px
gap; vertical centring is already upstream's align-items:center.

Why the label, and not the row

The row already had a fixed width:336px, which is exactly the label slot at the nominal
376px menu width — but the menu is capped by max-width: calc(100vw - 24px), so in a
narrow window the fixed row and the label slot stop agreeing and the check drifts. Both
sides of that relationship are ours to settle: the label is targeted structurally
([role=menu]:has(.cubgiG_searchShell)>[role=presentation]:first-child [role=menuitem]>span,
the same shape the existing rules in this patch use, so no upstream CSS hash is hardcoded),
and the row keeps its 336px with a max-width:100% guard against narrow windows.

How

  • the description span gains title: text.description ?? t("noDescription");
  • [role=menu]:has(…)…>[role=menuitem]>span{flex:0 1 auto;min-width:0} — the label hugs the row;
  • .cubgiG_item keeps width:336px and gains max-width:100%.

The single-line clamp, the 360px menu cap, the item name's truncation and the class map are
untouched.

Verification

  • npx patch-package: all 23 patches apply cleanly, including
    @deepseek-ai/dsh-client-ui-agent-preset@0.1.5-rc.2.
  • npm run typecheck: clean.
  • npm run build: succeeded (out/main/index.js, out/preload/index.cjs).
  • The applied bundle carries the change: in the installed
    node_modules/@deepseek-ai/dsh-client-ui-agent-preset/lib/client.js the row CSS and the
    title are present.
  • npx vitest run test/preset-transfer-patch.test.ts — 14 tests, 14 passed. The new case
    pins the tooltip, the hugging label and the capped row width.
  • npm test: 101 of 105 test files pass, 915 of 926 tests pass. The 3 failing files (9 tests)
    fail for reasons unrelated to this change and reproduce without it: 8 shell out to a
    python3 that this Windows machine does not have on PATH (only the Microsoft Store alias
    stub), and one needs symlink privileges (test/generation-installer.test.ts, EPERM on
    symlink). None of those three files references the agent-preset patch.
  • Live in the running app (npm run dev), Windows: screenshot below shows the check sitting
    beside the row and the tooltip carrying the full description.
8d0abf09fe6885470b028d7fc9b159e9

Notes

  • fix(agent-preset): make the preset picker readable in both colour modes #382 touches the same picker for colour contrast and edits the same line of the same patch
    (seatDesktopCss, line 72). The CSS strings do not overlap, but whichever lands first will
    move the other's hunk.
  • Per docs/harness-0.1.5-patch-refactor.md §L2 this whole package should eventually move into
    dsh-desktop-preset-transfer with the patch going to zero. This is the minimal fix for the
    interim; it does not change that plan.
  • Added two manual checks to docs/harness-0.1.5-rc.1-verification-checklist.md §2.1.

…over

The seat picker clips every mode description to one ellipsised line and nothing
recovers the tail: the row renders only a `<span class="itemDesc">`, with no `title`,
while the picker is the one surface that prints a mode's own summary.

Rather than spend a second line on every row, the description span now carries a
`title`, so the full text is on hover and the roster keeps the height it was laid out
for. The 360px menu cap and the single-line clamp stay exactly as they were.

While checking that in the running app, the row's trailing check turned out to sit well
away from the text. Upstream's `Menu.module.css` makes `.itemLabel` the flex child that
absorbs the row's spare width, and the check follows whatever width that child ends up
with — so a full-width label strands the check in the leftover space. The label is now
told to hug the row it labels, which puts the check back at the row's own 8px gap. The
row also gains `max-width:100%`: at a fixed 336px it could exceed a menu already capped
by `max-width: calc(100vw - 24px)`.

Tests: the description case pins the single line, the tooltip, the hugging label and the
capped row width; the roster case keeps its retargeted item-name assertion at 360px.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant