From ed4c04e57573bfede73c0838d11b821fbb05a65f Mon Sep 17 00:00:00 2001 From: SpencerJung Date: Fri, 22 May 2026 16:39:36 +0900 Subject: [PATCH] fix(cli): preserve CJK agent header text Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/cli/run/output-renderer.test.ts | 44 ++++++++++++++++++++++++++ src/cli/run/output-renderer.ts | 6 ++-- src/shared/agent-display-names.test.ts | 6 ++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/cli/run/output-renderer.test.ts diff --git a/src/cli/run/output-renderer.test.ts b/src/cli/run/output-renderer.test.ts new file mode 100644 index 000000000..36d36ab3e --- /dev/null +++ b/src/cli/run/output-renderer.test.ts @@ -0,0 +1,44 @@ +import { afterEach, describe, expect, it } from "bun:test" + +import { renderAgentHeader } from "./output-renderer" + +const originalWrite = process.stdout.write.bind(process.stdout) + +function captureStdout(run: () => void): string { + const chunks: string[] = [] + process.stdout.write = ((chunk: string | Uint8Array) => { + chunks.push(typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8")) + return true + }) as typeof process.stdout.write + + try { + run() + } finally { + process.stdout.write = originalWrite as typeof process.stdout.write + } + + return chunks.join("") +} + +afterEach(() => { + process.stdout.write = originalWrite as typeof process.stdout.write +}) + +describe("renderAgentHeader", () => { + it("preserves CJK agent display names in stdout output", () => { + const output = captureStdout(() => { + renderAgentHeader("Sisyphus - 主脑", "zhipu/glm-5.1", "xhigh", {}) + }) + + expect(output).toContain("Sisyphus - 主脑") + expect(output).toContain("zhipu/glm-5.1") + }) + + it("normalizes decomposed Unicode before rendering", () => { + const output = captureStdout(() => { + renderAgentHeader("헤파", null, null, {}) + }) + + expect(output).toContain("헤파") + }) +}) diff --git a/src/cli/run/output-renderer.ts b/src/cli/run/output-renderer.ts index 6c5782da4..2a376aa86 100644 --- a/src/cli/run/output-renderer.ts +++ b/src/cli/run/output-renderer.ts @@ -8,10 +8,12 @@ export function renderAgentHeader( ): void { if (!agent && !model) return + const normalizedAgent = agent?.normalize("NFC") ?? null + const normalizedModel = model?.normalize("NFC") ?? null const agentLabel = agent - ? pc.bold(colorizeWithProfileColor(agent, agentColorsByName[agent])) + ? pc.bold(colorizeWithProfileColor(normalizedAgent ?? agent, agentColorsByName[agent])) : "" - const modelBase = model ?? "" + const modelBase = normalizedModel ?? "" const variantSuffix = variant ? ` (${variant})` : "" const modelLabel = model ? pc.dim(`${modelBase}${variantSuffix}`) : "" diff --git a/src/shared/agent-display-names.test.ts b/src/shared/agent-display-names.test.ts index 2ce913743..eacfe467f 100644 --- a/src/shared/agent-display-names.test.ts +++ b/src/shared/agent-display-names.test.ts @@ -133,6 +133,12 @@ describe("getAgentDisplayName", () => { // then returns "multimodal-looker" expect(result).toBe("multimodal-looker") }) + + it("preserves CJK display-name overrides verbatim", () => { + expect(getAgentDisplayName("sisyphus", { sisyphus: { displayName: "Sisyphus - 主脑" } })).toBe("Sisyphus - 主脑") + expect(getAgentDisplayName("hephaestus", { hephaestus: { displayName: "헤파이스토스" } })).toBe("헤파이스토스") + expect(getAgentDisplayName("atlas", { atlas: { displayName: "アトラス" } })).toBe("アトラス") + }) }) describe("getAgentConfigKey", () => {