NousResearch/hermes-agent

Flag display in language selector debated

Cluster 29750. Data as of

Nothing open on GitHub. Fix merged in #29997 on 21 May 2026. Check it covers your case.

The short answer

0open issues
0open PRs
3items grouped
Known?
Yes. 3 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #29997. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #29997. That is separate from the fix event.
Still open
Nothing open on GitHub.

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.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #29997 fix(dashboard): remove country flags from language picker

    merged to main

    files: web/package.json, web/src/components/LanguageSwitcher.tsx, web/src/i18n/context.tsx, web/src/main.tsx

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

1 PR closed without merging

From the close comments: superseded by another PR 1

  • #29765 fix(web): show PRC flag for Traditional Chinese (繁體中文) · superseded by another PR → #29997
Closed issues · 1
  • Closed#29750[Bug]: Traditional Chinese (繁體中文) shows incorrect flag in language selector
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.67: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Merged PRs
#29997
Closed issues
1
Attempts
1 PR closed without merging
Fix link checked
21 May 2026

For your agent

The same facts, typed.