Skip to content

feat(workspaces): generated glyph icons for workspaces without a logo - #8488

Open
TheodoreSpeaks wants to merge 3 commits into
stagingfrom
generate-icons
Open

TheodoreSpeaks wants to merge 3 commits into
stagingfrom
generate-icons

Conversation

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator

Summary

  • Workspaces without an uploaded logo now get a generated glyph instead of their initial on a gray tile, so every workspace is recognizable in the switcher, search, org sidebar, invites, and resource menus
  • Glyph is deterministic from the workspace id (stable across renames): one of three blob families (burst, ring, glyph) drawn with the same goo filter as the chat thinking loader, monochrome in the icon gray
  • IdentityTile takes glyphSeed (workspaces) or initial (organizations, unchanged); uploaded logos still win
  • Removed the now-unused getWorkspaceInitial

Type of Change

  • New feature

Testing

  • Rendered generator output at 16px in light and dark to confirm legibility
  • glyph.test.ts: determinism, distinctness across seeds, every family stays centered inside the box, empty seed fails fast
  • bun run lint, check:audits, type-check passing

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

🤖 Generated with Claude Code

https://claude.ai/code/session_01C6q5mmZQrc7CTwpDV8ovR5

@vercel

vercel Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 1, 2026 1:26am UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 11 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

[Medium risk] Replaces workspace initials with generated glyph icons.

The PR appears safe to merge; the identified rendering-cost and test-coverage concerns are non-blocking.

Findings

  1. P2 Repeated glyph rendering work ▶
  2. P2 Rendered fallback remains untested ▶

Summary

The PR replaces initial-letter fallbacks for logo-less workspaces with deterministic, ID-seeded SVG glyphs across navigation, search, invitation, and resource surfaces. Uploaded logos retain priority; organization initials remain unchanged.

  • The glyph generator has determinism and geometry tests.
  • The switcher’s per-row rendering cost and the absence of component-level fallback tests merit follow-up.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Workspace ID and optional logo] --> B[IdentityTile]
  B -->|Logo present| C[Uploaded image]
  B -->|No logo| D[generateGlyph from workspace ID]
  D --> E[Filtered SVG glyph]
  F[Organization initial] --> B
  B -->|Organization without logo| G[Initial tile]
Loading

Reviews (1) · Last reviewed commit: "feat(workspaces): generated glyph icons ..."

Comment on lines +99 to +111
<filter
id={filterId}
x='-30%'
y='-30%'
width='160%'
height='160%'
colorInterpolationFilters='sRGB'
>
<feGaussianBlur stdDeviation='5' />
<feColorMatrix values={GOO_ALPHA_MATRIX} />
</filter>
<g filter={`url(#${filterId})`} fill='currentColor' stroke='currentColor'>
{generateGlyph(seed).map(glyphShape)}

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.

P2 Repeated glyph rendering work

The workspace switcher renders every filtered workspace. For each logo-less row, this component mounts a Gaussian-blur SVG filter and recalculates glyph shapes on every render, even when the workspace ID has not changed. Typing in the switcher repeats that work across the list, which can make larger workspace lists less responsive. Memoizing the glyph or limiting rendered rows would reduce the cost.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +37 to +43
describe('generateGlyph', () => {
it('is deterministic per seed', () => {
expect(generateGlyph('ws_abc')).toEqual(generateGlyph('ws_abc'))
})

it('gives nearly every seed a distinct glyph', () => {
const distinct = new Set(SEEDS.map((s) => JSON.stringify(generateGlyph(s))))

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.

P2 Rendered fallback remains untested

These tests call generateGlyph directly but never render IdentityTile. They therefore cannot catch a regression in uploaded-logo precedence or in how the SVG filter and shapes appear—the behavior users see. Component-level tests for a workspace with and without a logo would cover that gap.

This branch was previously deployed

1 inactive deployment
Preview — 73bc3af5 Deployed Oct 1, 2026 by vercel[bot]
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