Skip to content

fix(menu): stop clipping lifecycle actions behind a hidden scrollbar - #2716

Merged
kazemek21 merged 2 commits into
block:mainfrom
kazemek21:kylez_NEXUS-4264_solo-menu-delete-clipped
Nov 6, 2026
Merged

kazemek21 merged 2 commits into
block:mainfrom
kazemek21:kylez_NEXUS-4264_solo-menu-delete-clipped

Conversation

@kazemek21

@kazemek21 kazemek21 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

TL;DR

Delete chat was missing from the context menu of active, agent-created Solo chats. The permission was granted and the item was rendered, but it was clipped by the shared menu's fixed 24rem height cap, behind macOS's hidden overlay scrollbar. This bounds .buzz-menu-popup by the available viewport height only, so every permitted action is visible without scrolling.

Fixes NEXUS-4264

Diagnosis

  • Eligibility is correct. A plain member of an agent-created Solo chat gets Archive, Unarchive and Delete together from the owner-agent grant (the agent's verified NIP-OA attestation names the viewer). The relay authorizes 9008 delete the same way (actor_owns_any_owner_agent). Nothing about attestation, confirmation-time validation or relay authorization changes here.
  • The menu for that chat has 11 rows (huddle, mark unread, rename, settings, move, share, copy link, convert, leave, archive, delete). They need about 26.4rem, more than the min(24rem, var(--available-height)) cap, so Delete sits just past the fold. In the reported app (text scale 1.3) the popup measured at the 499.2px cap. An owner's channel menu has no Leave row and overflows by only a couple of pixels, which is why Delete still showed there. Rows and the rem cap grow together with text scale, so the clipping does not depend on it.
  • Playwright's click() scrolls items into view, so existing journeys could not catch this. DESIGN.md asks that long lists stay scrollable and all actions reachable; the viewport bound keeps the scroll fallback for genuinely short windows.

Change

  • src/shared/design-system/styles/components.css: .buzz-menu-popup max-height is now var(--available-height) (still overflow-y: auto). This is a shared design-system recipe, so it affects every menu: they grow up to the available viewport height instead of stopping at 24rem. That matches .buzz-select-popup and .buzz-popover-popup, which already use the uncapped viewport bound, so long lists in selects and popovers are unchanged. A viewport shorter than a menu still scrolls.
  • tests/browser/channel-lifecycle.spec.mjs: a new journey opens the Solo chat menu as a plain member whose agent owns the chat, then asserts that Leave, Archive and Delete are fully in the viewport, that the menu has no scroll overflow, and that no lifecycle event is published.

Browser-only justification: the defect is layout (computed height versus the scroll box), which jsdom cannot measure, and Playwright clicks would otherwise mask it. Fail-then-pass on a Blox workstation (chromium and webkit): before the fix the new case failed on the overflow check (Expected: 0, Received: 4); after it, channel-lifecycle, channel-archive-delete-pane and the design-system specs passed (30 tests, both engines), with Biome and design:check clean. The case runs at the default text scale on purpose: at 1.3 the 10-row fixture menu fits under the old cap (overflow 0 on base in both engines), so a scaled run would not catch the regression.

Deferred and related

Initiative status: https://g2.sqprod.co/apps/kylez-buzz-improvements-status

— Posted by Claude Code (claude-opus-5-5) on behalf of kylez

🤖 Generated with Claude Code

kazemek21 and others added 2 commits November 5, 2026 17:48
The shared menu popup capped its height at 24rem. With enlarged text, an
agent-owned Solo chat's 11-row menu exceeded the cap, so Delete chat sat
below the fold behind macOS's hidden overlay scrollbar and looked absent.
Bound the menu by the available viewport height only.

Fixes NEXUS-4264

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kyle Zemek <kylez@squareup.com>
Address first-push review: the comment no longer implies a menu can never
clip, and the journey notes why it runs at the default text scale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kyle Zemek <kylez@squareup.com>
@kazemek21
kazemek21 marked this pull request as ready for review November 6, 2026 02:20
@kazemek21
kazemek21 requested a review from a team as a code owner November 6, 2026 02:20

@dr0uleau dr0uleau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 approved at 8d44b66 -- CI passes. native macOS at text scale 1.3 remains unverified

@kazemek21
kazemek21 merged commit 3365da6 into block:main Nov 6, 2026
63 checks passed
wpfleger96 added a commit that referenced this pull request Nov 6, 2026
…leanup

* origin/main:
  feat(agents): let app-hosted agents read their owner's channels and members (#2745)
  NEXUS-4271: Expose installed plugin status (#2754)
  fix(menu): stop clipping lifecycle actions behind a hidden scrollbar (#2716)
  feat(agents): give approved external apps the selected agent's full Buzz tools (#2707)
  AIDA-2549: Keep Claude settings drafts in sync (#2841)
  fix(channels): keep a channel's side panels open when returning to it (#2838)
  fix(builderlab): clarify remote-agent account availability (#2764)
  fix(sidebar): rename Remove from Team to Close conversation (#2845)
  perf(channels): cut header and name-matching work in large channels (#2726)
  fix(browser): silence a browser page once its tab goes away (#2721)
  Community Mesh: shared compute plugin (including agent type) (#941)
  perf(relay): cut main-thread work from profile updates (#2730)
  fix(composer): lead the channel placeholder with its sidebar icon (#2829)
  test(activity): scope preview assertions to the request row (#2843)
  perf(search): fold people names once across palette keystrokes (#2570)
  fix(github): keep PR watches running when localStorage is full (#2699)
  Make drafts and sent part of Messages (#2728)
  fix(canvas): render every Canvas within the save limit (#2839)

# Conflicts:
#	.github/workflows/release.yml
cheng-block added a commit to cheng-block/buzz-app that referenced this pull request Nov 6, 2026
…ime-hint

* upstream/main:
  ci: give the native job room for a cold Rust cache (block#2867)
  fix(pairing): refuse unknown communities natively and name the requesting process (block#2835)
  Add per-interest Attention pause and management controls (block#2847)
  feat(drafts): show where unsent drafts wait (block#2853)
  feat(agents): let app-hosted agents read their owner's channels and members (block#2745)
  NEXUS-4271: Expose installed plugin status (block#2754)
  fix(menu): stop clipping lifecycle actions behind a hidden scrollbar (block#2716)
  feat(agents): give approved external apps the selected agent's full Buzz tools (block#2707)
  AIDA-2549: Keep Claude settings drafts in sync (block#2841)
  fix(channels): keep a channel's side panels open when returning to it (block#2838)
  fix(builderlab): clarify remote-agent account availability (block#2764)
  fix(sidebar): rename Remove from Team to Close conversation (block#2845)
  perf(channels): cut header and name-matching work in large channels (block#2726)
  fix(browser): silence a browser page once its tab goes away (block#2721)
  Community Mesh: shared compute plugin (including agent type) (block#941)
  perf(relay): cut main-thread work from profile updates (block#2730)
  fix(composer): lead the channel placeholder with its sidebar icon (block#2829)
  test(activity): scope preview assertions to the request row (block#2843)
  perf(search): fold people names once across palette keystrokes (block#2570)
  fix(github): keep PR watches running when localStorage is full (block#2699)

Signed-off-by: Cheng Peng <cheng@block.xyz>
Co-authored-by: Cursor <cursoragent@cursor.com>
cheng-block added a commit to cheng-block/buzz-app that referenced this pull request Nov 6, 2026
…ions-literal-markdown

* upstream/main: (38 commits)
  fix(composer): let Option+Up/Down switch conversations from an empty composer (block#2832)
  fix(reactions): Scope timed reactions to the selected video (block#2796)
  fix(communities): name what the Join dialog is doing instead of "Working…" (block#2822)
  docs(agents): explain the per-conversation MCP cost of Claude agents (block#2683)
  fix(avatars): keep unsaved avatar drafts and focus, and validate the URL late (block#2714)
  fix(agents): offer stream and forum connection setup only to channel members (block#2749)
  Describe Attention as what the agent does, not its tools (block#2865)
  Let a local Codex agent join its owner's huddle by voice (block#2321)
  ci: give the native job room for a cold Rust cache (block#2867)
  fix(pairing): refuse unknown communities natively and name the requesting process (block#2835)
  Add per-interest Attention pause and management controls (block#2847)
  feat(drafts): show where unsent drafts wait (block#2853)
  feat(agents): let app-hosted agents read their owner's channels and members (block#2745)
  NEXUS-4271: Expose installed plugin status (block#2754)
  fix(menu): stop clipping lifecycle actions behind a hidden scrollbar (block#2716)
  feat(agents): give approved external apps the selected agent's full Buzz tools (block#2707)
  AIDA-2549: Keep Claude settings drafts in sync (block#2841)
  fix(channels): keep a channel's side panels open when returning to it (block#2838)
  fix(builderlab): clarify remote-agent account availability (block#2764)
  fix(sidebar): rename Remove from Team to Close conversation (block#2845)
  ...

Signed-off-by: Cheng Peng <cheng@block.xyz>
Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants