Skip to content

Generated per-person avatars, and a direct settings control - #282

Merged
TheGreatAxios merged 4 commits into
mainfrom
cl-generated-avatars
Aug 22, 2026
Merged

Generated per-person avatars, and a direct settings control#282
TheGreatAxios merged 4 commits into
mainfrom
cl-generated-avatars

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Summary

  • Every human's fallback avatar (no explicit picture) now gets a deterministic, per-principal color instead of the same flat gray circle agents already stood apart from — reusing @corbits/presence's colorForPrincipal (already shipped for live cursors) paired with a computed black/white initials color for legibility in both themes.
  • Applied everywhere a human avatar renders: chat timeline, the @-mention list, PR-thread replies, the workbench header's presence stack, the sidebar account row, and Settings' account card — which now also honors a real profile image (UserProfile.image) when one exists, previously ignored entirely.
  • Fixed a dead CSS selector ([data-slot="avatar"]) that never matched react-ui's actual Avatar markup, so the sidebar avatar's intended sizing silently never applied.
  • Splits the sidebar's bottom-left account row into avatar+name (still the popup-menu trigger for weekly usage/feedback/log out) plus a direct settings gear — Settings was two clicks away, now one, with nothing from the old menu stranded.
  • Updates DESIGN.md's Account row bullet to match.

Upstream gap: react-ui's Avatar has no style prop and a closed AvatarTone enum, so the per-person fill is implemented as CSS custom properties set on an ancestor and read back via a .avatar-identity-generated class rather than a first-class prop. Flagged in CL-6570 for react-ui to grow an identity-color escape hatch if this need shows up elsewhere.

Closes CL-6570.

Test plan

  • bun run typecheck in packages/chat-ui, packages/settings-ui, apps/web — all clean
  • bun test in packages/chat-ui (674 pass), packages/settings-ui (142 pass), apps/web (845 pass, 3 pre-existing unrelated failures needing bun run build first, confirmed failing identically on unmodified origin/main)
  • eslint on all changed files — clean
  • bunx prettier --write on all changed files
  • Visual check in the running app (light + dark) — not done here per the dev-machine/port constraint on this lane

Covers determinism/distinctness/legibility for a person's generated
fallback avatar, an explicit image still winning, and the sidebar
settings icon navigating in one click without opening the account menu.
Every human's fallback avatar (chat messages, mention list, PR-thread
replies, the header presence stack, the sidebar account row, and
Settings' own account card) now gets a deterministic, per-principal fill
instead of the same flat gray circle agents already stood apart from —
reusing @corbits/presence's colorForPrincipal (already shipped for live
cursors) rather than a second hashing scheme, paired with a computed
black/white initials color so it stays legible in both themes regardless
of hue. An explicit profile image, when present, still wins.

Also splits the sidebar's bottom-left account row into two controls:
avatar+name keeps opening the popup menu (weekly usage, feedback, log
out), and a new settings gear navigates straight to Settings in one
click instead of two. Nothing from the old menu is stranded.

react-ui's Avatar takes no `style` prop (only `className`), so the fill
is set as CSS custom properties on an ancestor and read back via a
`.avatar-identity-generated` class — no react-ui change needed. The
underlying gap (Avatar's tone system is a closed enum with no
per-principal option) belongs upstream if this needs to grow past a
CSS-variable workaround.
…y color

DESIGN.md's Account row bullet described Settings as reachable only
through the popup menu; it now has its own one-click icon. Also notes
the generated-avatar exception to "tokens only" for color.
…ace without

A className written as a literal plus an interpolation tokenized as
["a-b", "${X}"], so the class-list exemption never applied and the class
name was reported as user copy. Shape is now decided with interpolations
blanked; whitespace is still decided on the literal as written, since
blanking substitutes spaces and would make a key like `bench:${id}` look
like prose.
@TheGreatAxios
TheGreatAxios merged commit 0244105 into main Aug 22, 2026
5 checks passed
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