refactor(agents): drop ZWSP prefixes from agent display names

The sort shim from the previous commit enforces canonical core ordering at runtime, so ZWSP prefixes are no longer needed. Removing them eliminates the Bun.stringWidth vs terminal-width drift that broke the TUI status bar (#3259).

Drop AGENT_LIST_SORT_PREFIXES and getAgentRuntimeName from agent-display-names; switch all call sites to getAgentDisplayName. getAgentListDisplayName stays as a thin alias for external importers.

Keep stripInvisibleAgentCharacters and the ZWSP regex paths so legacy session state and configs from v3.14.0-v3.16.0 still resolve.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-27 17:36:05 +09:00
parent dffe5a305b
commit 333ad3aadd
13 changed files with 201 additions and 70 deletions
@@ -9,7 +9,7 @@ import type { OhMyOpenCodeConfig } from "../config"
import * as agentLoader from "../features/claude-code-agent-loader"
import * as skillLoader from "../features/opencode-skill-loader"
import type { LoadedSkill } from "../features/opencode-skill-loader"
import { getAgentListDisplayName, getAgentRuntimeName } from "../shared/agent-display-names"
import { getAgentDisplayName, getAgentListDisplayName } from "../shared/agent-display-names"
import { applyAgentConfig } from "./agent-config-handler"
import type { PluginComponents } from "./plugin-components-loader"
@@ -205,7 +205,7 @@ describe("applyAgentConfig builtin override protection", () => {
})
// then
expect(config.default_agent).toBe(getAgentRuntimeName("sisyphus"))
expect(config.default_agent).toBe(getAgentDisplayName("sisyphus"))
})
test("keeps config-key default_agent behavior unchanged", async () => {
@@ -222,7 +222,7 @@ describe("applyAgentConfig builtin override protection", () => {
})
// then
expect(config.default_agent).toBe(getAgentRuntimeName("sisyphus"))
expect(config.default_agent).toBe(getAgentDisplayName("sisyphus"))
})
test("keeps fallback default_agent behavior unchanged", async () => {
@@ -238,7 +238,25 @@ describe("applyAgentConfig builtin override protection", () => {
})
// then
expect(config.default_agent).toBe(getAgentRuntimeName("sisyphus"))
expect(config.default_agent).toBe(getAgentDisplayName("sisyphus"))
})
test("resolved default_agent contains no zero-width invisible characters", async () => {
// given canonical core ordering is now enforced by the agent sort shim, so
// default_agent must not carry the legacy ZWSP prefix that earlier biased
// OpenCode's localeCompare sort.
const config = createBaseConfig()
// when applyAgentConfig resolves the default agent
await applyAgentConfig({
config,
pluginConfig: createPluginConfig(),
ctx: { directory: "/tmp" },
pluginComponents: createPluginComponents(),
})
// then the persisted default_agent is the clean display name
expect(config.default_agent).not.toMatch(/[\u200B\u200C\u200D\uFEFF]/)
})
test("filters user agents whose key matches the builtin display-name alias", async () => {
@@ -262,7 +280,7 @@ describe("applyAgentConfig builtin override protection", () => {
// then
expect(result[BUILTIN_SISYPHUS_DISPLAY_NAME]).toEqual({
...builtinSisyphusConfig,
name: getAgentRuntimeName("sisyphus"),
name: getAgentDisplayName("sisyphus"),
})
})
@@ -287,7 +305,7 @@ describe("applyAgentConfig builtin override protection", () => {
// then
expect(result[BUILTIN_SISYPHUS_DISPLAY_NAME]).toEqual({
...builtinSisyphusConfig,
name: getAgentRuntimeName("sisyphus"),
name: getAgentDisplayName("sisyphus"),
})
expect(result.SiSyPhUs).toBeUndefined()
})
@@ -314,7 +332,7 @@ describe("applyAgentConfig builtin override protection", () => {
// then
expect(result[BUILTIN_SISYPHUS_DISPLAY_NAME]).toEqual({
...builtinSisyphusConfig,
name: getAgentRuntimeName("sisyphus"),
name: getAgentDisplayName("sisyphus"),
})
})