From 0502580eb5ac5d2056a1a5c1534a10f250fedc7b Mon Sep 17 00:00:00 2001 From: chief-archivist Date: Wed, 21 Oct 2026 02:23:46 +0200 Subject: [PATCH 1/2] fix(client-runtime): instance badges ignore punctuation Badge initials took the first character of each word, so "Codex (hub)" became C(. Punctuation now separates words, so it reads CH. An apostrophe between letters stays inside its word ("Theo's Codex" is TC); a quoting one does not ("Codex 'hub'" is CH). Co-Authored-By: Claude Opus 5.5 --- .../src/state/providerInstanceDisplay.test.ts | 9 +++++++++ .../client-runtime/src/state/providerInstanceDisplay.ts | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/client-runtime/src/state/providerInstanceDisplay.test.ts b/packages/client-runtime/src/state/providerInstanceDisplay.test.ts index 7068a761605a1..27129f11128b3 100644 --- a/packages/client-runtime/src/state/providerInstanceDisplay.test.ts +++ b/packages/client-runtime/src/state/providerInstanceDisplay.test.ts @@ -12,6 +12,15 @@ const codex = ProviderDriverKind.make("codex"); const acpRegistry = ProviderDriverKind.make("acpRegistry"); describe("providerInstanceInitials", () => { + it("treats punctuation as a word break but keeps apostrophes between letters", () => { + expect(providerInstanceInitials("Codex (hub)")).toBe("CH"); + expect(providerInstanceInitials("work_codex")).toBe("WC"); + expect(providerInstanceInitials("Theo's Codex")).toBe("TC"); + expect(providerInstanceInitials("Codex 'hub'")).toBe("CH"); + expect(providerInstanceInitials("‘hub’")).toBe("HU"); + expect(providerInstanceInitials("(hub)")).toBe("HU"); + }); + it("keeps an emoji whole instead of splitting its surrogate pair", () => { expect(providerInstanceInitials("😀 Work")).toBe("😀W"); expect(providerInstanceInitials("😀")).toBe("😀"); diff --git a/packages/client-runtime/src/state/providerInstanceDisplay.ts b/packages/client-runtime/src/state/providerInstanceDisplay.ts index 64d1d941f1122..3e506bcdfdacd 100644 --- a/packages/client-runtime/src/state/providerInstanceDisplay.ts +++ b/packages/client-runtime/src/state/providerInstanceDisplay.ts @@ -27,7 +27,13 @@ export function resolveProviderInstanceDisplayName( } export function providerInstanceInitials(label: string): string { - const words = label.replace(/[_-]+/g, " ").split(/\s+/u).filter(Boolean); + // Punctuation separates words so "Codex (hub)" reads CH, not C(. An apostrophe + // between letters stays inside its word ("Theo's Codex" is TC); a quoting one + // does not ("Codex 'hub'" is CH). + const words = label + .replace(/(?:[^\P{P}'’]|(? Date: Wed, 21 Oct 2026 06:35:03 -0700 Subject: [PATCH 2/2] refactor(client-runtime): split badge punctuation handling into two plain steps Replace the lookaround regex with two steps: punctuation other than apostrophes becomes a space, then each word drops leading and trailing apostrophes. Same results, easier to read. Co-Authored-By: Claude Opus 5.5 --- .../client-runtime/src/state/providerInstanceDisplay.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/client-runtime/src/state/providerInstanceDisplay.ts b/packages/client-runtime/src/state/providerInstanceDisplay.ts index 3e506bcdfdacd..62f65445e8217 100644 --- a/packages/client-runtime/src/state/providerInstanceDisplay.ts +++ b/packages/client-runtime/src/state/providerInstanceDisplay.ts @@ -28,11 +28,12 @@ export function resolveProviderInstanceDisplayName( export function providerInstanceInitials(label: string): string { // Punctuation separates words so "Codex (hub)" reads CH, not C(. An apostrophe - // between letters stays inside its word ("Theo's Codex" is TC); a quoting one - // does not ("Codex 'hub'" is CH). + // inside a word stays ("Theo's Codex" is TC); a quoting one does not + // ("Codex 'hub'" is CH). const words = label - .replace(/(?:[^\P{P}'’]|(? word.replace(/^['’]+|['’]+$/gu, "")) .filter(Boolean); if (words.length === 0) return ""; if (words.length === 1) return Array.from(words[0]!).slice(0, 2).join("").toUpperCase();