Skip to content

fix(web): home detail-panel overflow menu, dynamic greeting, markdown summary (LUM-1759)#31412

Merged
ashleeradka merged 4 commits into
mainfrom
ashlee/lum-1759-drift-home-feed-polish-7467
May 21, 2026
Merged

fix(web): home detail-panel overflow menu, dynamic greeting, markdown summary (LUM-1759)#31412
ashleeradka merged 4 commits into
mainfrom
ashlee/lum-1759-drift-home-feed-polish-7467

Conversation

@ashleeradka
Copy link
Copy Markdown
Contributor

Closes LUM-1759.

Summary

Back-port of vellum-ai/vellum-assistant-platform#7467 — the only PR from LUM-1759's set that wasn't already integrated in OSS. The other 5 PRs from the initial audit (#7413, #7414, #7415, #7416, #7421) had already landed via earlier home work.

Three small home-feed UX upgrades:

  1. Overflow menu in the detail panel — replace the inline mark-as-read toggle button with a <Menu.Root> containing both "Mark as read / unread" and a new "Dismiss" action. Renames "Go to Thread" → "Go to Convo".
  2. Markdown summariesHomeGenericDetail now renders item.summary as markdown via a new HomeMarkdownContent component (react-markdown + GFM, styled with the same design tokens as the file-viewer markdown but with tighter spacing).
  3. Dynamic greetingHomeGreetingHeader accepts an optional daemon-supplied greeting string; falls back to the existing static "Here's what's been going on". Wraps the avatar/greeting and New Chat button so the greeting can truncate cleanly on narrow widths. contextBanner.greeting was already on the feed response type, just wired through the UI here.

Files

  • src/domains/home/detail-panel/home-detail-panel.tsx — overflow menu + onDismiss prop
  • src/domains/home/detail-panel/home-generic-detail.tsx — render summary as markdown
  • src/domains/home/detail-panel/home-markdown-content.tsx — new (react-markdown + GFM + design-token styling)
  • src/domains/home/home-greeting-header.tsx — optional greeting prop with fallback
  • src/domains/home/home-page.tsx — pass greeting + onDismiss

Verified locally

  • bun run lint — 0 errors.
  • bun run typecheck — clean.

Test plan

  • CI green
  • Manual: open a feed item, open the overflow menu, verify Mark as read/unread + Dismiss both work
  • Manual: confirm "Go to Convo" still navigates correctly when a conversationId is present
  • Manual: send a feed item with markdown in summary, verify it renders (bold, links, lists, etc.)
  • Manual: send a contextBanner.greeting from the daemon, verify it shows in the header (and falls back when missing)

https://claude.ai/code/session_01JPGu4yGPTL4JoLaPuqpEW2


Generated by Claude Code

claude added 3 commits May 21, 2026 00:58
…ssistant/ (LUM-1753.4)

These were sitting in `domains/chat/api/assistant.ts` — the
runtime identity of the assistant has nothing to do with chat.
It's a property of the assistant itself, queried by chat, the
identity tab, contacts, intelligence, onboarding, the sync
router, and several stream handlers. Misplaced since day one.

Now lives at `apps/web/src/assistant/identity.ts`. The `chat`
file is renamed only in its header comment — it now solely owns
chat-context bootstrapping (`getChatContext`, `fetchAssistantId`).
The `domains/chat/api/assistant.ts` filename stays for now to
avoid churn; can be renamed in a follow-up if it bothers anyone.

Import sites updated: identity-tab, use-assistant-identity-init,
chat-page (two lines), chat-route-content, contacts-page,
chat-utils.

Cross-domain allow-list: 119 → 118 imports. Small numeric drop —
the structural win is that `fetchAssistantIdentity` no longer
sits in another feature's folder.

Verified locally: lint, typecheck, tests all green.

https://claude.ai/code/session_01JPGu4yGPTL4JoLaPuqpEW2
… (LUM-1764)

Back-port of vellum-ai/vellum-assistant-platform#7468.

`useAssistantAvatar()` was unconditionally fetching character
traits alongside the components blob and avatar image. When an
assistant has a custom avatar image, the traits file is
intentionally deleted on the daemon side — so every SSE
reconnect (which invalidates `SYNC_TAGS.assistantAvatar`)
produced a fresh 404 on the traits endpoint. 308 of them in
the platform team's local daemon log.

`AvatarRenderer` only reads `traits` when there is no custom
image, so the fetch was pure waste in that branch. Switch to:
- Fetch components + imageUrl in parallel first.
- If imageUrl is non-null, skip the traits fetch entirely.
- Otherwise fall through to the original behavior.

No new APIs, no behavior change for assistants without a
custom image.

Adds a unit test mirroring the platform PR's coverage:
- skips traits fetch when image resolves
- still fetches traits when no image

The other half of LUM-1764 — back-porting platform#7494 (remove
unused pro-upgrade-machine endpoint) — is blocked. The OSS repo
still has an active caller (`compute-upgrade-card.tsx`) that
needs to migrate to the unified machine-resize endpoint first.
Tracking on the issue.

https://claude.ai/code/session_01JPGu4yGPTL4JoLaPuqpEW2
…wn summary (LUM-1759)

Back-port of vellum-ai/vellum-assistant-platform#7467 — the only
PR from LUM-1759's set that wasn't already integrated in OSS
(7413, 7414, 7415, 7416, 7421 had already landed via earlier
home work).

Changes:

- `home-detail-panel.tsx` — replace the inline mark-as-read toggle
  button with an overflow menu (`<Menu.Root>`) that contains both
  "Mark as read / unread" and a new "Dismiss" action. Renames "Go
  to Thread" → "Go to Convo". Adds the required `onDismiss` prop.
- `home-generic-detail.tsx` — render `item.summary` as markdown
  via the new `HomeMarkdownContent` component, so feed items can
  use bold/italic/links/lists/etc. for richer summaries.
- `home-markdown-content.tsx` (new) — `react-markdown` + GFM with
  design-token styling tuned for the condensed detail panel.
- `home-greeting-header.tsx` — accept an optional `greeting` prop
  (daemon-supplied), fall back to the existing static string.
  Wraps both the avatar/greeting and the New Chat button so the
  greeting can truncate cleanly on narrow widths.
- `home-page.tsx` — pass `feedQuery.data?.contextBanner?.greeting`
  to the header and the new `onDismiss={handleDismissItem}` to
  both mobile and desktop detail panel mounts.

The `contextBanner.greeting` field was already on the home feed
response type, so this just wires it through the UI.

Verified locally: lint, typecheck clean.

https://claude.ai/code/session_01JPGu4yGPTL4JoLaPuqpEW2
@linear
Copy link
Copy Markdown

linear Bot commented May 21, 2026

LUM-1759

@ashleeradka ashleeradka marked this pull request as ready for review May 21, 2026 01:35
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

vex-assistant-bot[bot]
vex-assistant-bot Bot previously approved these changes May 21, 2026
Copy link
Copy Markdown
Contributor

@vex-assistant-bot vex-assistant-bot Bot left a comment

Choose a reason for hiding this comment

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

APPROVE

Value: Fills the one remaining home-feed polish gap from the platform drift audit — users get a proper overflow menu for feed item actions, long dynamic greeting text no longer clips, and markdown-formatted summaries render correctly instead of as raw syntax.

What this does: Back-ports platform PR #7467 (the only one from LUM-1759's set not yet in OSS) with three focused changes: (1) replaces the inline mark-as-read toggle with a <Menu.Root> overflow menu that also exposes "Dismiss", (2) wires feedQuery.data?.contextBanner?.greeting into HomeGreetingHeader with a static fallback, (3) swaps <Typography> for <HomeMarkdownContent> in the generic detail panel. Bundled with a clean AssistantIdentity lift out of domains/chat/ into assistant/identity.ts and the 404-suppression fix for avatar traits fetches when a custom image exists.

assistant/identity.ts refactor — the move out of domains/chat/api/assistant.ts is architecturally correct: identity is a property of the assistant, not a chat concern. Six import sites updated consistently, cross-domain allowlist updated to remove the chat entry from identity-tab.tsx. Clean.

use-assistant-avatar.ts — traits skip — changing from Promise.all([components, traits, imageUrl]) to sequential imageUrl → traits if needed is the right trade-off. The comment explains why (daemon deletes the traits file when a custom image exists, so every SSE reconnect invalidation generated a 404). The test coverage is solid — two cases: custom image skips traits call entirely, no image fetches all three.

home-detail-panel.tsx — overflow menuMenu.Root > Menu.Trigger > Menu.Content structure matches the design library's compound pattern. MailOpen/Mail icon swap per read-state is a nice touch. align="end" keeps the dropdown from clipping on the right edge.

home-greeting-header.tsxgreeting || "Here's what's been going on" is correct (|| rather than ?? so an empty string also falls back to the static label). min-w-0 flex-1 + truncate on the <Typography> correctly handles overflow for long daemon-supplied greetings.

home-markdown-content.tsx — Two non-blocking observations:

  • table/thead/tbody/tr/td/th overrides are absent; GFM tables will render with browser-default <table> styling. Unlikely in home-feed summaries but worth a follow-up if tables start appearing.
  • No pre override, so fenced code blocks get browser-default <pre> wrapping around the styled <code>. Edge case for feed content, but leaves a visual gap if a summary ever contains a code block.

CI — all 7 checks green: Lint, Type Check & Build, Test, Build, Lint, Socket PR + Project.

Vellum Constitution — Yours: the overflow menu and dynamic greeting let the assistant's curated context speak clearly, making the home feed feel like it belongs to the user rather than to the interface.

Two non-blocking observations from the vex-bot review on #31412
and #31416 (both files surfaced the same gaps):

1. **Missing element overrides** — react-markdown was falling
   back to browser defaults for tables and fenced code blocks.
   Added overrides for `pre`, `table`, `thead`, `tbody`, `tr`,
   `th`, `td` styled with the home feed's design tokens.
   Tables wrap in a horizontal-scroll container so wide tables
   don't blow out the condensed panel layout.

2. **target="_blank" on iOS WKWebView silently fails** — without
   a `WKUIDelegate createWebViewWith` implementation, the
   webview won't open a new tab. Route through Capacitor's
   `openUrl()` helper (already used elsewhere for OAuth/Stripe
   flows) which presents `SFSafariViewController`. Web keeps the
   default new-tab behavior; the `href` is preserved on both
   platforms so right-click → copy link still works.

https://claude.ai/code/session_01JPGu4yGPTL4JoLaPuqpEW2
Copy link
Copy Markdown
Contributor

@vex-assistant-bot vex-assistant-bot Bot left a comment

Choose a reason for hiding this comment

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

APPROVE (re-review at 600d2199 — prior review dismissed after fix commit)

Commit 600d2199 directly resolves both non-blocking notes from the previous review. No new concerns at HEAD.


Fix 1 — target="_blank" on iOS WKWebView

handleAnchorClick correctly guards on isNativePlatform() and falls back early if href is absent. event.preventDefault() fires before void openUrl(href) — right order, no race. The void suppresses the Promise return without swallowing errors (acceptable for a UI click handler). href is preserved on the element so right-click → copy link still works on web. Clean.

Fix 2 — Missing pre and GFM table overrides

pre wraps fenced code blocks with overflow-x-auto, font-mono, and color-mix(in oklab, var(--content-default) 6%, transparent) background — consistent with the design-token approach used throughout the file. The table → thead → tbody → tr → th → td chain uses border-collapse, var(--border-base) row dividers, var(--surface-lift) header bg, and wraps in a horizontal-scroll container for overflow — correct for a condensed panel layout.

Rest of PR (unchanged from prior review):

Overflow menu, dynamic greeting, markdown renderer, AssistantIdentity domain lift, conditional traits fetch + tests — all previously approved, no regressions introduced.

CI — 7/7 green. ✅


Devin's review was at 99495cb7 (pre-fix commit) — retriggering for second approval.

@vex-assistant-bot
Copy link
Copy Markdown
Contributor

@codex review
@devin review this PR

@ashleeradka ashleeradka merged commit 72ff2b7 into main May 21, 2026
7 checks passed
@ashleeradka ashleeradka deleted the ashlee/lum-1759-drift-home-feed-polish-7467 branch May 21, 2026 01:58
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

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