Add off-by-default provider marks to sidebar thread rows - #452
Merged
Merged
Conversation
Every provider now has a color: built-in profiles carry a hand-picked brand color and every user-added provider (custom profiles, ACP agents) takes a slot from a fixed palette. Slots come from an FNV-1a hash of the thread's provider color key, with known custom providers walked in sorted order and bumped past collisions, so colors are deterministic across devices without persisted state and configured providers never share a color while the palette has room. With the new default-on "Provider colors" switch (Settings → General → Appearance, stored inverted as `provider_colors_disabled`), wide thread rows use the provider hue at three alpha steps (rest 0.08, hover 0.16, active 0.26) and compact rows take the resting wash under the existing selected surface and semantic washes. Off restores the neutral rows. Owners: `Settings::provider_color` / `crates/core/src/provider_colors.rs` for assignment, `SessionMeta::provider_color_key` for the key, and `WorkspaceStore::provider_color` for the setting-gated read.
`ProviderSettings::accent_rgb` is now the one parser of the card's `#rrggbb` accent; `WorkspaceStore::provider_profile_accent` and `Settings::provider_color` both call it, so a user-set accent wins over the brand color and the palette for that profile's rows. ACP keys are not profile ids and keep their palette slot. zh-CN wording follows the locale's 提供方 term for provider.
Thread rows return to their neutral rest, hover, selected and semantic surfaces. With Provider colors on, every row shape (grouped, flat parent and child, compact) instead paints its provider's glyph under the content: ~1.25x the row height, vertically centred, hanging 6px past the right edge so the row's clip cuts it, in the provider color at 0.14 alpha. The mark has no handlers; ACP agents use the box glyph the rail and ACP panel already use. The Claude brand color now lives only in core: `provider_glyph` and the favorite star read `builtin_provider_color` instead of a UI constant.
The glyph is now sized to the row height minus an 8px inset, vertically centred and right-aligned inside the row's own horizontal padding, so nothing overhangs and rows keep their original (unclipped) overflow. Alpha rises to 0.18 to compensate for the smaller mark.
Raise the mark's alpha from 0.18 to 0.32 so the fitted glyph reads on both canvases.
`provider_colors_disabled` becomes `sidebar_provider_marks: bool` (`SettingsPatch::SidebarProviderMarks`), absent in legacy files → off. The General row is "Provider marks", non-inverted, with its reset action shown while on. Color assignment (accent → brand → palette) is untouched.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Every provider now has a color, and an opt-in Provider marks switch (Settings → General → Appearance, off by default) draws each thread's provider logo in that color at the right edge of its sidebar row. The mark is decorative only: it fits inside the row (row height − 8px), sits under the row's content, takes no input, and leaves the row's rest / hover / selected / semantic surfaces exactly as they were.
Changes
crates/core/src/provider_colors.rsholds the four built-in brand colors (Claude#D97757Anthropic Clay, Codex#8B5CF6, pi#4D9ABFfrom its logo, OpenCode#22A06B) and a ten-hue palette for everything the user adds.Settings::provider_color(key)resolves a card'saccent_colorfirst, then the brand color, then a palette slot chosen by a stable FNV-1a hash of the key with collision bumping across the configured user profiles and ACP agents, so known providers never share a color while the palette has room and no assignment has to be persisted.SessionMeta::provider_color_keyderives the key from a non-built-inprofile_id, elseacp:<agent id>, else the built-in provider key.CLAUDE_BRAND_COLORin the UI is gone;provider_glyphand the composer's favourite star readbuiltin_provider_color.ProviderSettings::accent_rgbis the single#rrggbbparser, and the store'sprovider_profile_accentnow calls it.provider_markinsidebar.rsrenders the glyph (provider_glyphfor native kinds, the ACP box for agents) atPROVIDER_MARK_ALPHA0.32 in a right-aligned square box, attached to the grouped, flat (parent and child) and compact row shapes.Settings::sidebar_provider_marks(#[serde(default)], legacy files → off),SettingsPatch::SidebarProviderMarks, store intent, toggle row with reset action,settings.sidebar_provider_marksstrings inen.ymlandzh-CN.yml. Restore defaults turns it off.docs/DESIGN.mdSidebar and Settings sections describe the mark contract and the switch.Test plan
cargo fmt --all --checkcargo clippy --workspace --all-targets --locked -- -D warningscargo test -p tcode-core -p tcode-ui -p tcode-runtime --locked(136 / 422 / 174 passed) — new: palette determinism and distinctness, accent-over-brand precedence, color key resolution, default-off + patch, reset clears the switch, locale parity, and a GPUI sidebar test that enables the switch through the store, asserts both marks sit inside their rows and the active row still paintslist_active, then disables it and asserts the marks are gone.cargo build --workspace --lockedTCODE_DATA_DIRcopy of a real session index; screenshots of flat and grouped layouts in light and dark confirmed Codex and Claude marks are distinguishable and the row surfaces are unchanged.