{"repo":"NousResearch/hermes-agent","public_id":"29750","display_label":"Flag display in language selector debated","summary":"These items concern a bug where Traditional Chinese showed an incorrect flag, an attempted fix assigning a PRC flag, and a subsequent change to remove country flags from the language picker entirely. The members reflect an ongoing discussion about how to represent language options without implying national identity.","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":29997,"merged_at":"2026-05-21T20:10:52+00:00"},"resolution":{"state":"resolved","by":"pr-29997"},"freshness":{"state":"verified","last_verified_at":"2026-05-21T20:10:52+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.6666666666666666},"fix_edges":[{"issue_number":29750,"pr_number":29997,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-05-21T20:10:52+00:00"}],"members":[{"kind":"issue","number":29750,"title":"[Bug]: Traditional Chinese (繁體中文) shows incorrect flag in language selector","url":null,"state":"closed"},{"kind":"pr","number":29765,"title":"fix(web): show PRC flag for Traditional Chinese (繁體中文)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#29997","number":29997}],"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":29997,"title":"fix(dashboard): remove country flags from language picker","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["web/package.json","web/src/components/LanguageSwitcher.tsx","web/src/i18n/context.tsx","web/src/main.tsx"],"fix_hunks":[{"file":"web/package-lock.json","hunks":["@@ -19,7 +19,6 @@\n         \"@xterm/xterm\": \"^6.0.0\",\n         \"class-variance-authority\": \"^0.7.1\",\n         \"clsx\": \"^2.1.1\",\n-        \"flag-icons\": \"^7.5.0\",\n         \"gsap\": \"^3.15.0\",\n         \"leva\": \"^0.10.1\",\n         \"lucide-react\": \"^0.577.0\",","@@ -78,7 +77,6 @@\n       \"integrity\": \"sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==\",\n       \"dev\": true,\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"@babel/code-frame\": \"^7.29.0\",\n         \"@babel/generator\": \"^7.29.0\",","@@ -1129,7 +1127,6 @@\n       \"resolved\": \"https://registry.npmjs.org/@observablehq/plot/-/plot-0.6.17.tgz\",\n       \"integrity\": \"sha512-/qaXP/7mc4MUS0s4cPPFASDRjtsWp85/TbfsciqDgU1HwYixbSbbytNuInD8AcTYC3xaxACgVX06agdfQy9W+g==\",\n       \"license\": \"ISC\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"d3\": \"^7.9.0\",\n         \"interval-tree-1d\": \"^1.0.0\",","@@ -1868,7 +1865,6 @@\n       \"resolved\": \"https://registry.npmjs.org/@react-three/fiber/-/fiber-9.6.0.tgz\",\n       \"integrity\": \"sha512-90abYK2q5/qDM+GACs9zRvc5KhEEpEWqWlHSd64zTPNxg+9wCJvTfyD9x2so7hlQhjRYO1Fa6flR3BC/kpTFkA==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"@babel/runtime\": \"^7.17.8\",\n         \"@types/webxr\": \"*\",","@@ -2574,7 +2570,6 @@\n       \"integrity\": \"sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==\",\n       \"devOptional\": true,\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"undici-types\": \"~7.16.0\"\n       }","@@ -2584,7 +2579,6 @@\n       \"resolved\": \"https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz\",\n       \"integrity\": \"sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"csstype\": \"^3.2.2\"\n       }","@@ -2595,7 +2589,6 @@\n       \"integrity\": \"sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==\",\n       \"devOptional\": true,\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"peerDependencies\": {\n         \"@types/react\": \"^19.2.0\"\n       }","@@ -2660,7 +2653,6 @@\n       \"integrity\": \"sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==\",\n       \"dev\": true,\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"@typescript-eslint/scope-manager\": \"8.59.1\",\n         \"@typescript-eslint/types\": \"8.59.1\",","@@ -2989,7 +2981,6 @@\n       \"integrity\": \"sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==\",\n       \"dev\": true,\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"bin\": {\n         \"acorn\": \"bin/acorn\"\n       },","@@ -3142,7 +3133,6 @@\n         }\n       ],\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"baseline-browser-mapping\": \"^2.10.12\",\n         \"caniuse-lite\": \"^1.0.30001782\",","@@ -3650,7 +3640,6 @@\n       \"resolved\": \"https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz\",\n       \"integrity\": \"sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==\",\n       \"license\": \"ISC\",\n-      \"peer\": true,\n       \"engines\": {\n         \"node\": \">=12\"\n       }","@@ -3970,7 +3959,6 @@\n       \"integrity\": \"sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==\",\n       \"dev\": true,\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"@eslint-community/eslint-utils\": \"^4.8.0\",\n         \"@eslint-community/regexpp\": \"^4.12.1\",","@@ -4250,12 +4238,6 @@\n         \"url\": \"https://github.com/sponsors/sindresorhus\"\n       }\n     },\n-    \"node_modules/flag-icons\": {\n-      \"version\": \"7.5.0\",\n-      \"resolved\": \"https://registry.npmjs.org/flag-icons/-/flag-icons-7.5.0.tgz\",\n-      \"integrity\": \"sha512-kd+MNXviFIg5hijH766tt+3x76ele1AXlo4zDdCxIvqWZhKt4T83bOtxUOOMlTx/EcFdUMH5yvQgYlFh1EqqFg==\",\n-      \"license\": \"MIT\"\n-    },\n     \"node_modules/flat-cache\": {\n       \"version\": \"4.0.1\",\n       \"resolved\": \"https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz\",","@@ -4382,8 +4364,7 @@\n       \"version\": \"3.15.0\",\n       \"resolved\": \"https://registry.npmjs.org/gsap/-/gsap-3.15.0.tgz\",\n       \"integrity\": \"sha512-dMW4CWBTUK1AEEDeZc1g4xpPGIrSf9fJF960qbTZmN/QwZIWY5wgliS6JWl9/25fpTGJrMRtSjGtOmPnfjZB+A==\",\n-      \"license\": \"Standard 'no charge' license: https://gsap.com/standard-license.\",\n-      \"peer\": true\n+      \"license\": \"Standard 'no charge' license: https://gsap.com/standard-license.\"\n     },\n     \"node_modules/has-flag\": {\n       \"version\": \"4.0.0\",","@@ -4698,7 +4679,6 @@\n       \"resolved\": \"https://registry.npmjs.org/leva/-/leva-0.10.1.tgz\",\n       \"integrity\": \"sha512-BcjnfUX8jpmwZUz2L7AfBtF9vn4ggTH33hmeufDULbP3YgNZ/C+ss/oO3stbrqRQyaOmRwy70y7BGTGO81S3rA==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"@radix-ui/react-portal\": \"^1.1.4\",\n         \"@radix-ui/react-tooltip\": \"^1.1.8\",","@@ -5106,7 +5086,6 @@\n       \"resolved\": \"https://registry.npmjs.org/motion/-/motion-12.39.0.tgz\",\n       \"integrity\": \"sha512-H4a+Ze+a9j+/NTla5ezfb/g9vmIOxC+viDj++NGDZyTZkdRKjiOz3kSv6TalRWM8ZmD2y/CfC6TkQc97ybyqSA==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"framer-motion\": \"^12.39.0\",\n         \"tslib\": \"^2.4.0\"","@@ -5179,7 +5158,6 @@\n         }\n       ],\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"engines\": {\n         \"node\": \"^20.0.0 || >=22.0.0\"\n       }","@@ -5307,7 +5285,6 @@\n       \"resolved\": \"https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz\",\n       \"integrity\": \"sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"engines\": {\n         \"node\": \">=12\"\n       },","@@ -5379,7 +5356,6 @@\n       \"resolved\": \"https://registry.npmjs.org/react/-/react-19.2.5.tgz\",\n       \"integrity\": \"sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"engines\": {\n         \"node\": \">=0.10.0\"\n       }","@@ -5399,7 +5375,6 @@\n       \"resolved\": \"https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz\",\n       \"integrity\": \"sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"scheduler\": \"^0.27.0\"\n       },","@@ -5760,8 +5735,7 @@\n       \"version\": \"0.180.0\",\n       \"resolved\": \"https://registry.npmjs.org/three/-/three-0.180.0.tgz\",\n       \"integrity\": \"sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==\",\n-      \"license\": \"MIT\",\n-      \"peer\": true\n+      \"license\": \"MIT\"\n     },\n     \"node_modules/tinyglobby\": {\n       \"version\": \"0.2.16\",","@@ -5826,7 +5800,6 @@\n       \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\n       \"dev\": true,\n       \"license\": \"Apache-2.0\",\n-      \"peer\": true,\n       \"bin\": {\n         \"tsc\": \"bin/tsc\",\n         \"tsserver\": \"bin/tsserver\"","@@ -5925,7 +5898,6 @@\n       \"resolved\": \"https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz\",\n       \"integrity\": \"sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"peerDependencies\": {\n         \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\n       }","@@ -5941,7 +5913,6 @@\n       \"resolved\": \"https://registry.npmjs.org/vite/-/vite-7.3.2.tgz\",\n       \"integrity\": \"sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==\",\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"dependencies\": {\n         \"esbuild\": \"^0.27.0\",\n         \"fdir\": \"^6.5.0\",","@@ -6063,7 +6034,6 @@\n       \"integrity\": \"sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==\",\n       \"dev\": true,\n       \"license\": \"MIT\",\n-      \"peer\": true,\n       \"funding\": {\n         \"url\": \"https://github.com/sponsors/colinhacks\"\n       }"]},{"file":"web/package.json","hunks":["@@ -21,7 +21,6 @@\n     \"@xterm/xterm\": \"^6.0.0\",\n     \"class-variance-authority\": \"^0.7.1\",\n     \"clsx\": \"^2.1.1\",\n-    \"flag-icons\": \"^7.5.0\",\n     \"gsap\": \"^3.15.0\",\n     \"leva\": \"^0.10.1\",\n     \"lucide-react\": \"^0.577.0\","]},{"file":"web/src/components/LanguageSwitcher.tsx","hunks":["@@ -9,15 +9,16 @@ import type { Locale } from \"@/i18n\";\n import { cn } from \"@/lib/utils\";\n \n /**\n- * Language picker — shows the current language's flag + endonym, opens a\n- * dropdown of all supported locales when clicked.  Persists choice to\n- * localStorage via the I18n context.\n+ * Language picker — shows the current language's endonym, opens a dropdown\n+ * of all supported locales when clicked.  Persists choice to localStorage via\n+ * the I18n context.\n  *\n  * Replaces the older two-state EN↔ZH toggle now that we ship 16 locales\n  * (en, zh, zh-hant, ja, de, es, fr, tr, uk, af, ko, it, ga, pt, ru, hu).\n  *\n- * Locale markers use lipis/flag-icons (SVG sprites) instead of emoji so flags\n- * render consistently across platforms.\n+ * No country flags by design — languages aren't countries, and flag pairings\n+ * inevitably create political mismappings (e.g. Mandarin variants ≠ any single\n+ * jurisdiction, English ≠ GB, Portuguese ≠ PT). Endonyms are unambiguous.\n  *\n  * When placed at the bottom of the sidebar (next to ThemeSwitcher), pass\n  * `dropUp` so the list opens above the trigger and avoids clipping below the","@@ -71,7 +72,6 @@ export function LanguageSwitcher({ dropUp = false }: LanguageSwitcherProps) {\n         className=\"px-2 py-1 normal-case tracking-normal font-normal text-xs text-muted-foreground hover:text-foreground\"\n       >\n         <span className=\"inline-flex items-center gap-1.5\">\n-          <LocaleFlagIcon countryCode={current.flagCountryCode} />\n           <Typography\n             mondwest\n             className=\"hidden sm:inline tracking-wide uppercase text-[0.65rem]\"","@@ -146,8 +146,6 @@ function LanguageSwitcherOptions({\n             role=\"option\"\n             type=\"button\"\n           >\n-            <LocaleFlagIcon countryCode={meta.flagCountryCode} />\n-\n             <span className=\"truncate\">{meta.name}</span>\n \n             {selected && <span className=\"ml-auto text-xs\">✓</span>}","@@ -158,15 +156,6 @@ function LanguageSwitcherOptions({\n   );\n }\n \n-function LocaleFlagIcon({ countryCode }: LocaleFlagIconProps) {\n-  return (\n-    <span\n-      aria-hidden\n-      className={cn(\"fi fis shrink-0 text-base leading-none\", `fi-${countryCode}`)}\n-    />\n-  );\n-}\n-\n interface LanguageSwitcherOptionsProps {\n   allLocales: Array<[Locale, (typeof LOCALE_META)[Locale]]>;\n   locale: Locale;","@@ -177,7 +166,3 @@ interface LanguageSwitcherOptionsProps {\n interface LanguageSwitcherProps {\n   dropUp?: boolean;\n }\n-\n-interface LocaleFlagIconProps {\n-  countryCode: string;\n-}"]},{"file":"web/src/i18n/context.tsx","hunks":["@@ -37,27 +37,31 @@ const TRANSLATIONS: Record<Locale, Translations> = {\n };\n \n // Display metadata for the language picker — endonym (native name) so users\n-// recognize their language even if they don't speak the current UI language,\n-// plus a flag-icons sprite (ISO 3166-1 alpha-2) for visual scanning.\n+// recognize their language even if they don't speak the current UI language.\n // Exposed as a constant so the LanguageSwitcher and any future settings page\n // can share the same list.\n-export const LOCALE_META: Record<Locale, { name: string; flagCountryCode: string }> = {\n-  en: { name: \"English\", flagCountryCode: \"gb\" },\n-  zh: { name: \"简体中文\", flagCountryCode: \"cn\" },\n-  \"zh-hant\": { name: \"繁體中文\", flagCountryCode: \"tw\" },\n-  ja: { name: \"日本語\", flagCountryCode: \"jp\" },\n-  de: { name: \"Deutsch\", flagCountryCode: \"de\" },\n-  es: { name: \"Español\", flagCountryCode: \"es\" },\n-  fr: { name: \"Français\", flagCountryCode: \"fr\" },\n-  tr: { name: \"Türkçe\", flagCountryCode: \"tr\" },\n-  uk: { name: \"Українська\", flagCountryCode: \"ua\" },\n-  af: { name: \"Afrikaans\", flagCountryCode: \"za\" },\n-  ko: { name: \"한국어\", flagCountryCode: \"kr\" },\n-  it: { name: \"Italiano\", flagCountryCode: \"it\" },\n-  ga: { name: \"Gaeilge\", flagCountryCode: \"ie\" },\n-  pt: { name: \"Português\", flagCountryCode: \"pt\" },\n-  ru: { name: \"Русский\", flagCountryCode: \"ru\" },\n-  hu: { name: \"Magyar\", flagCountryCode: \"hu\" },\n+//\n+// We intentionally do NOT pair locales with country flags. Languages are not\n+// countries (English ≠ GB, Portuguese ≠ PT, Spanish ≠ ES, Chinese variants ≠\n+// any single jurisdiction). Endonyms are unambiguous and avoid the political\n+// mismapping that flag pairings inevitably create.\n+export const LOCALE_META: Record<Locale, { name: string }> = {\n+  en: { name: \"English\" },\n+  zh: { name: \"简体中文\" },\n+  \"zh-hant\": { name: \"繁體中文\" },\n+  ja: { name: \"日本語\" },\n+  de: { name: \"Deutsch\" },\n+  es: { name: \"Español\" },\n+  fr: { name: \"Français\" },\n+  tr: { name: \"Türkçe\" },\n+  uk: { name: \"Українська\" },\n+  af: { name: \"Afrikaans\" },\n+  ko: { name: \"한국어\" },\n+  it: { name: \"Italiano\" },\n+  ga: { name: \"Gaeilge\" },\n+  pt: { name: \"Português\" },\n+  ru: { name: \"Русский\" },\n+  hu: { name: \"Magyar\" },\n };\n \n const SUPPORTED_LOCALES = Object.keys(TRANSLATIONS) as Locale[];"]},{"file":"web/src/main.tsx","hunks":["@@ -1,6 +1,5 @@\n import { createRoot } from \"react-dom/client\";\n import { BrowserRouter } from \"react-router-dom\";\n-import \"flag-icons/css/flag-icons.min.css\";\n import \"./index.css\";\n import App from \"./App\";\n import { SystemActionsProvider } from \"./contexts/SystemActions\";\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}