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:
- Per-slot token priority:
editorGutter.{added,deleted,modified}Background → diffEditor.{inserted,removed}TextBackground → terminal.ansiGreen/ansiRed → gitDecoration.* last.
- Strip alpha, never composite. The alpha was VS Code's own blending; Hunk does its own blending downstream.
- 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).
- 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.
- 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
What happened?
Problem
BUNDLED_SHIKI_THEME_DIFF_COLORSinsrc/core/theme/catalog.tsis 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.buildShikiThemethen 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 storedremovedvalue byte-for-byte:#f0717890over bgremoved#263238→#98565c#98565c(exact)#212121→#964e52#964e52(exact)#0f111a→#8e474f#8e474f(exact)#292d3e→#99535f#99535f(exact)Same exact-match math holds for material-theme-lighter (
#e5393590over#fafafa→#ee8d8b), night-owl (#ef535090over#011627→#87383e), and everforest, where all six stored values aregitDecoration.*ResourceForegroundtokens (which carrya0alpha) flattened over the editor background (e.g.#e67e80a0over#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 inheritedgitDecoration.*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
#7a8c66/#a16366/#608986gitDecoration.{added,deleted,modified}ResourceForeground(#a7c080a0/#e67e80a0/#7fbbb3a0) flattened#a7c080/#e67e80/#7fbbb3#b7c155/#fa9188/#83b9d0#8da101a0/#f85552a0/#3a94c5a0) flattened#8da101/#f85552/#3a94c5#87383egitDecoration.deletedResourceForeground #ef535090flattened#ef5350(editorGutter.deletedBackground)#98565cfamily#f0717890/#82aaff90flattened#f07178,#82aaff#24a075/#60c9a0list.warningForeground #27d797b3flattened#29d398(terminal.ansiGreen)#63c89e,#ae8cc4#72f1b8cc/#b893ceeeflattened (milder)#72f1b8,#b893ceB. Mis-sourced token where the theme publishes real diff accents
#ebdbb2dark /#3c3836lightgitDecoration.addedResourceForegroundto the editor foreground; added rows tint beige/grey,+sign is text-colorededitorGutter.addedBackground#b8bb26/#79740e#908caa/#797593#eb6f92(editorGutter.deletedBackground,diffEditor.removedTextBackground)#b381c5; modified duplicates added#eb64b9(editorGutter.deletedBackground),#40b4c4(modified)#449dab,#914c54diffEditor.*#41a6b5/#db4b4b#ffffff(white!), added/modified =#ecb22eyellow#e0e0e0badge.backgroundgreyterminal.ansiRed-style tokens exist for the other slotsThemes 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
buildShikiThemederives 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:
editorGutter.{added,deleted,modified}Background→diffEditor.{inserted,removed}TextBackground→terminal.ansiGreen/ansiRed→gitDecoration.*last.scripts/generate-theme-diff-colors.ts) so the table is regenerable against@shikijs/themesand provenance can't silently drift again.Steps to reproduce
hunk diffwith an affected theme, outlined aboveExpected behavior
No response
Version
0.19.0