{"repo":"NousResearch/hermes-agent","public_id":"40364","display_label":"Emoji rendering fix for Hermes Desktop","summary":"A bug was reported and addressed regarding emoji not displaying correctly on Hermes Desktop. The fix involves adding a color-emoji font fallback to ensure proper emoji rendering.","subsystem":null,"counts":{"members":3,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":1},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":40928,"merged_at":"2026-06-07T02:58:40+00:00"},"resolution":{"state":"resolved","by":"pr-40928"},"freshness":{"state":"verified","last_verified_at":"2026-06-07T02:58:40+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.6666666666666666},"fix_edges":[{"issue_number":40364,"pr_number":40928,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-06-07T02:58:40+00:00"}],"members":[{"kind":"issue","number":40364,"title":"[Bug]: Emoji in Hermes Desktop not showing correctly","url":null,"state":"closed"},{"kind":"pr","number":40388,"title":"fix(desktop): add color-emoji font fallback so emoji render (#40364)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"bec07964b","number":0},{"kind":"commit","value":"fe2942a5a","number":0},{"kind":"pr","value":"#40928","number":40928}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":40928,"title":"fix(desktop): color-emoji font fallback so emoji render (#40364)","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["apps/desktop/src/styles.css","apps/desktop/src/themes/presets.test.ts","apps/desktop/src/themes/presets.ts"],"fix_hunks":[{"file":"apps/desktop/src/styles.css","hunks":["@@ -266,8 +266,10 @@\n     --dt-user-bubble: var(--ui-chat-bubble-background);\n     --dt-user-bubble-border: var(--ui-stroke-tertiary);\n \n-    --dt-font-sans: 'Segoe WPC', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;\n-    --dt-font-mono: 'Cascadia Code', 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace;\n+    --dt-font-sans: 'Segoe WPC', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif,\n+      'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', emoji;\n+    --dt-font-mono: 'Cascadia Code', 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace,\n+      'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', emoji;\n     --dt-base-size: 1rem;\n     --dt-line-height: 1.5;\n     --dt-letter-spacing: 0;"]},{"file":"apps/desktop/src/themes/presets.test.ts","hunks":["@@ -0,0 +1,33 @@\n+import { describe, expect, it } from 'vitest'\n+\n+import { BUILTIN_THEME_LIST, DEFAULT_TYPOGRAPHY, EMOJI_FALLBACK } from './presets'\n+\n+// #40364: none of the UI text/mono fonts carry emoji glyphs, so every font\n+// stack must end with a color-emoji fallback or emoji render as tofu on\n+// platforms whose default font lacks them (e.g. Linux).\n+describe('theme typography emoji fallback (#40364)', () => {\n+  const stacks: Array<[string, string]> = [\n+    ['DEFAULT_TYPOGRAPHY.fontSans', DEFAULT_TYPOGRAPHY.fontSans],\n+    ['DEFAULT_TYPOGRAPHY.fontMono', DEFAULT_TYPOGRAPHY.fontMono],\n+    // A theme may override only fontMono (fontSans then falls back to the\n+    // default, which already carries the emoji stack), so skip undefined.\n+    ...BUILTIN_THEME_LIST.flatMap(theme =>\n+      (\n+        [\n+          [`${theme.name}.fontSans`, theme.typography?.fontSans],\n+          [`${theme.name}.fontMono`, theme.typography?.fontMono]\n+        ] as Array<[string, string | undefined]>\n+      ).filter((entry): entry is [string, string] => typeof entry[1] === 'string')\n+    )\n+  ]\n+\n+  it.each(stacks)('%s includes a color-emoji font', (_label, stack) => {\n+    expect(stack).toMatch(/Apple Color Emoji|Segoe UI Emoji|Noto Color Emoji|(^|,\\s*)emoji\\b/)\n+  })\n+\n+  it('EMOJI_FALLBACK lists the major platform emoji fonts', () => {\n+    expect(EMOJI_FALLBACK).toContain('Apple Color Emoji')\n+    expect(EMOJI_FALLBACK).toContain('Segoe UI Emoji')\n+    expect(EMOJI_FALLBACK).toContain('Noto Color Emoji')\n+  })\n+})"]},{"file":"apps/desktop/src/themes/presets.ts","hunks":["@@ -5,10 +5,19 @@\n \n import type { DesktopTheme, DesktopThemeTypography } from './types'\n \n+// Color-emoji fonts to append to every stack as a last resort. None of the UI\n+// text/mono fonts carry emoji glyphs, so without this emoji render as tofu\n+// boxes on platforms whose default text font lacks them (e.g. Linux/#40364).\n+// Covers macOS, Windows, Linux, plus the `emoji` generic for anything else.\n+export const EMOJI_FALLBACK =\n+  '\"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\", emoji'\n+\n const SYSTEM_SANS =\n-  '\"Segoe WPC\", \"Segoe UI\", -apple-system, BlinkMacSystemFont, \"SF Pro Text\", \"SF Pro Display\", system-ui, sans-serif'\n+  '\"Segoe WPC\", \"Segoe UI\", -apple-system, BlinkMacSystemFont, \"SF Pro Text\", \"SF Pro Display\", system-ui, sans-serif, ' +\n+  EMOJI_FALLBACK\n \n-const SYSTEM_MONO = '\"Cascadia Code\", \"JetBrains Mono\", \"SF Mono\", ui-monospace, Menlo, Monaco, Consolas, monospace'\n+const SYSTEM_MONO =\n+  '\"Cascadia Code\", \"JetBrains Mono\", \"SF Mono\", ui-monospace, Menlo, Monaco, Consolas, monospace, ' + EMOJI_FALLBACK\n \n export const DEFAULT_TYPOGRAPHY: DesktopThemeTypography = { fontSans: SYSTEM_SANS, fontMono: SYSTEM_MONO }\n ","@@ -228,8 +237,8 @@ export const cyberpunkTheme: DesktopTheme = {\n     userBubbleBorder: '#004800'\n   },\n   typography: {\n-    fontMono: `\"Courier New\", Courier, monospace`,\n-    fontSans: `\"Courier New\", Courier, monospace`\n+    fontMono: `\"Courier New\", Courier, monospace, ${EMOJI_FALLBACK}`,\n+    fontSans: `\"Courier New\", Courier, monospace, ${EMOJI_FALLBACK}`\n   }\n }\n \n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}