Files
oh-my-opencode/src/plugin-handlers/command-config-handler.test.ts
T
YeonGyu-Kim 15c8d469bc refactor(command-config): use getAgentListDisplayName for consistent naming
Update command config handler and tests to use getAgentListDisplayName

for proper agent name resolution in command configurations.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 22:01:42 +09:00

161 lines
6.0 KiB
TypeScript

/// <reference types="bun-types" />
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test";
import * as builtinCommands from "../features/builtin-commands";
import * as commandLoader from "../features/claude-code-command-loader";
import * as skillLoader from "../features/opencode-skill-loader";
import type { OhMyOpenCodeConfig } from "../config";
import type { PluginComponents } from "./plugin-components-loader";
import { applyCommandConfig } from "./command-config-handler";
import {
getAgentDisplayName,
getAgentListDisplayName,
} from "../shared/agent-display-names";
function createPluginComponents(): PluginComponents {
return {
commands: {},
skills: {},
agents: {},
mcpServers: {},
hooksConfigs: [],
plugins: [],
errors: [],
};
}
function createPluginConfig(): OhMyOpenCodeConfig {
return {
git_master: {
commit_footer: true,
include_co_authored_by: true,
git_env_prefix: "GIT_MASTER=1",
},
};
}
describe("applyCommandConfig", () => {
let loadBuiltinCommandsSpy: ReturnType<typeof spyOn>;
let loadUserCommandsSpy: ReturnType<typeof spyOn>;
let loadProjectCommandsSpy: ReturnType<typeof spyOn>;
let loadOpencodeGlobalCommandsSpy: ReturnType<typeof spyOn>;
let loadOpencodeProjectCommandsSpy: ReturnType<typeof spyOn>;
let discoverConfigSourceSkillsSpy: ReturnType<typeof spyOn>;
let loadUserSkillsSpy: ReturnType<typeof spyOn>;
let loadProjectSkillsSpy: ReturnType<typeof spyOn>;
let loadOpencodeGlobalSkillsSpy: ReturnType<typeof spyOn>;
let loadOpencodeProjectSkillsSpy: ReturnType<typeof spyOn>;
let loadProjectAgentsSkillsSpy: ReturnType<typeof spyOn>;
let loadGlobalAgentsSkillsSpy: ReturnType<typeof spyOn>;
beforeEach(() => {
loadBuiltinCommandsSpy = spyOn(builtinCommands, "loadBuiltinCommands").mockReturnValue({});
loadUserCommandsSpy = spyOn(commandLoader, "loadUserCommands").mockResolvedValue({});
loadProjectCommandsSpy = spyOn(commandLoader, "loadProjectCommands").mockResolvedValue({});
loadOpencodeGlobalCommandsSpy = spyOn(commandLoader, "loadOpencodeGlobalCommands").mockResolvedValue({});
loadOpencodeProjectCommandsSpy = spyOn(commandLoader, "loadOpencodeProjectCommands").mockResolvedValue({});
discoverConfigSourceSkillsSpy = spyOn(skillLoader, "discoverConfigSourceSkills").mockResolvedValue([]);
loadUserSkillsSpy = spyOn(skillLoader, "loadUserSkills").mockResolvedValue({});
loadProjectSkillsSpy = spyOn(skillLoader, "loadProjectSkills").mockResolvedValue({});
loadOpencodeGlobalSkillsSpy = spyOn(skillLoader, "loadOpencodeGlobalSkills").mockResolvedValue({});
loadOpencodeProjectSkillsSpy = spyOn(skillLoader, "loadOpencodeProjectSkills").mockResolvedValue({});
loadProjectAgentsSkillsSpy = spyOn(skillLoader, "loadProjectAgentsSkills").mockResolvedValue({});
loadGlobalAgentsSkillsSpy = spyOn(skillLoader, "loadGlobalAgentsSkills").mockResolvedValue({});
});
afterEach(() => {
loadBuiltinCommandsSpy.mockRestore();
loadUserCommandsSpy.mockRestore();
loadProjectCommandsSpy.mockRestore();
loadOpencodeGlobalCommandsSpy.mockRestore();
loadOpencodeProjectCommandsSpy.mockRestore();
discoverConfigSourceSkillsSpy.mockRestore();
loadUserSkillsSpy.mockRestore();
loadProjectSkillsSpy.mockRestore();
loadOpencodeGlobalSkillsSpy.mockRestore();
loadOpencodeProjectSkillsSpy.mockRestore();
loadProjectAgentsSkillsSpy.mockRestore();
loadGlobalAgentsSkillsSpy.mockRestore();
});
test("includes .agents skills in command config", async () => {
// given
loadProjectAgentsSkillsSpy.mockResolvedValue({
"agents-project-skill": {
description: "(project - Skill) Agents project skill",
template: "template",
},
});
loadGlobalAgentsSkillsSpy.mockResolvedValue({
"agents-global-skill": {
description: "(user - Skill) Agents global skill",
template: "template",
},
});
const config: Record<string, unknown> = { command: {} };
// when
await applyCommandConfig({
config,
pluginConfig: createPluginConfig(),
ctx: { directory: "/tmp" },
pluginComponents: createPluginComponents(),
});
// then
const commandConfig = config.command as Record<string, { description?: string }>;
expect(commandConfig["agents-project-skill"]?.description).toContain("Agents project skill");
expect(commandConfig["agents-global-skill"]?.description).toContain("Agents global skill");
});
test("normalizes Atlas command agents to the runtime list name used by opencode command routing", async () => {
// given
loadBuiltinCommandsSpy.mockReturnValue({
"start-work": {
name: "start-work",
description: "(builtin) Start work",
template: "template",
agent: "atlas",
},
});
const config: Record<string, unknown> = { command: {} };
// when
await applyCommandConfig({
config,
pluginConfig: createPluginConfig(),
ctx: { directory: "/tmp" },
pluginComponents: createPluginComponents(),
});
// then
const commandConfig = config.command as Record<string, { agent?: string }>;
expect(commandConfig["start-work"]?.agent).toBe(getAgentListDisplayName("atlas"));
});
test("normalizes legacy display-name command agents to the runtime list name", async () => {
// given
loadBuiltinCommandsSpy.mockReturnValue({
"start-work": {
name: "start-work",
description: "(builtin) Start work",
template: "template",
agent: getAgentDisplayName("atlas"),
},
});
const config: Record<string, unknown> = { command: {} };
// when
await applyCommandConfig({
config,
pluginConfig: createPluginConfig(),
ctx: { directory: "/tmp" },
pluginComponents: createPluginComponents(),
});
// then
const commandConfig = config.command as Record<string, { agent?: string }>;
expect(commandConfig["start-work"]?.agent).toBe(getAgentListDisplayName("atlas"));
});
});