Skip to content

Bundled diff-color catalog stores mis-sourced VS Code theme tokens #823

Description

@masonmcelvain

What happened?

Problem

BUNDLED_SHIKI_THEME_DIFF_COLORS in src/core/theme/catalog.ts is supposed to hold each bundled theme's semantic added/removed/modified accents. For ~25 of the 66 themes, the stored values are not accents: they were taken from VS Code theme tokens with the wrong semantics — file-explorer label colors (gitDecoration.*), alpha background tokens flattened onto the editor background at harvest time, or unrelated tokens entirely. buildShikiTheme then treats these values as saturated accents and composites them onto the background again, producing washed-out or wrong-hue diff rows, signs, and badges.

Evidence that the values are flattened composites

The material-theme family shares one VS Code token, gitDecoration.deletedResourceForeground: #f0717890. Compositing that single alpha token over each variant's different background reproduces each variant's different stored removed value byte-for-byte:

Theme #f0717890 over bg Stored removed
material-theme over #263238#98565c #98565c (exact)
material-theme-darker over #212121#964e52 #964e52 (exact)
material-theme-ocean over #0f111a#8e474f #8e474f (exact)
material-theme-palenight over #292d3e#99535f #99535f (exact)

Same exact-match math holds for material-theme-lighter (#e5393590 over #fafafa#ee8d8b), night-owl (#ef535090 over #011627#87383e), and everforest, where all six stored values are gitDecoration.*ResourceForeground tokens (which carry a0 alpha) flattened over the editor background (e.g. #e67e80a0 over #2d353b#a16366). Four sibling themes producing four different constants that are all exact alpha composites of the same source token rules out hand-picked coincidence: however the table was populated, it flattened alpha tokens and inherited gitDecoration.* semantics, and no sourcing rule was documented (#450 has no generation script or comment about the method).

Affected themes

A. Flattened alpha composites stored as accents

Theme Slot(s) Stored Actually is Real accent in theme JSON
everforest-dark all three #7a8c66 / #a16366 / #608986 gitDecoration.{added,deleted,modified}ResourceForeground (#a7c080a0 / #e67e80a0 / #7fbbb3a0) flattened palette green/red/blue #a7c080 / #e67e80 / #7fbbb3
everforest-light all three #b7c155 / #fa9188 / #83b9d0 same tokens (#8da101a0 / #f85552a0 / #3a94c5a0) flattened #8da101 / #f85552 / #3a94c5
night-owl removed #87383e gitDecoration.deletedResourceForeground #ef535090 flattened #ef5350 (editorGutter.deletedBackground)
material-theme ×5 removed, modified #98565c family #f0717890 / #82aaff90 flattened #f07178, #82aaff
horizon, horizon-bright added #24a075 / #60c9a0 list.warningForeground #27d797b3 flattened #29d398 (terminal.ansiGreen)
synthwave-84 added, modified #63c89e, #ae8cc4 #72f1b8cc / #b893ceee flattened (milder) #72f1b8, #b893ce

B. Mis-sourced token where the theme publishes real diff accents

Theme Slot(s) Stored Problem Better source in theme JSON
gruvbox ×6 added #ebdbb2 dark / #3c3836 light gruvbox sets gitDecoration.addedResourceForeground to the editor foreground; added rows tint beige/grey, + sign is text-colored editorGutter.addedBackground #b8bb26 / #79740e
rose-pine ×3 removed #908caa / #797593 rosé pine's muted purple for deleted file labels; deleted rows read purple-grey love red #eb6f92 (editorGutter.deletedBackground, diffEditor.removedTextBackground)
laserwave removed, modified #b381c5; modified duplicates added lavender from gitDecoration; modified == added #eb64b9 (editorGutter.deletedBackground), #40b4c4 (modified)
tokyo-night added, removed #449dab, #914c54 deliberately dimmed gitDecoration labels used instead of diff tokens diffEditor.* #41a6b5 / #db4b4b
slack-dark, slack-ochin all removed = #ffffff (white!), added/modified = #ecb22e yellow theme publishes no usable diff tokens none — drop the entries so the generic fallback applies
min-light modified #e0e0e0 literally badge.background grey terminal.ansiRed-style tokens exist for the other slots

Themes whose values are genuine palette accents and are fine as data: github ×7, catppuccin, dracula, nord, kanagawa, ayu, houston, plastic, vitesse, monokai, snazzy-light, and solarized.

Why users see it

buildShikiTheme derives everything downstream from these values: sign colors, row tints (addedBg/removedBg), word-level emphasis tints, sidebar badges, and file-state colors. A pre-blended or muted stored value means:

Proposed fix

Re-harvest the table under a documented, scripted sourcing policy instead of patching themes one at a time:

  1. Per-slot token priority: editorGutter.{added,deleted,modified}BackgrounddiffEditor.{inserted,removed}TextBackgroundterminal.ansiGreen/ansiRedgitDecoration.* last.
  2. Strip alpha, never composite. The alpha was VS Code's own blending; Hunk does its own blending downstream.
  3. Validate each candidate by hue class and saturation (removed must be red-family, added green/teal-family); a failing candidate falls through to the next source. If nothing passes, omit the entry so Hunk's generic fallback applies (this fixes slack).
  4. Check the harvester in (e.g. scripts/generate-theme-diff-colors.ts) so the table is regenerable against @shikijs/themes and provenance can't silently drift again.
  5. Table-driven regression tests across all 66 themes: removed is red-family, added is green/teal-family, and stored values are 6-digit palette tokens, not composites.

Steps to reproduce

hunk diff with an affected theme, outlined above

Expected behavior

No response

Version

0.19.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions