fix(commands): load .agents skills into command config
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -48,6 +48,20 @@ export async function loadOpencodeProjectSkills(directory?: string): Promise<Rec
|
||||
return skillsToCommandDefinitionRecord(deduplicateSkillsByName(allSkills.flat()))
|
||||
}
|
||||
|
||||
export async function loadProjectAgentsSkills(directory?: string): Promise<Record<string, CommandDefinition>> {
|
||||
const agentsProjectSkillDirs = findProjectAgentsSkillDirs(directory ?? process.cwd())
|
||||
const allSkills = await Promise.all(
|
||||
agentsProjectSkillDirs.map((skillsDir) => loadSkillsFromDir({ skillsDir, scope: "project" })),
|
||||
)
|
||||
return skillsToCommandDefinitionRecord(deduplicateSkillsByName(allSkills.flat()))
|
||||
}
|
||||
|
||||
export async function loadGlobalAgentsSkills(): Promise<Record<string, CommandDefinition>> {
|
||||
const agentsGlobalDir = join(homedir(), ".agents", "skills")
|
||||
const skills = await loadSkillsFromDir({ skillsDir: agentsGlobalDir, scope: "user" })
|
||||
return skillsToCommandDefinitionRecord(skills)
|
||||
}
|
||||
|
||||
export interface DiscoverSkillsOptions {
|
||||
includeClaudeCodePaths?: boolean
|
||||
directory?: string
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
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";
|
||||
|
||||
function createPluginComponents(): PluginComponents {
|
||||
return {
|
||||
commands: {},
|
||||
skills: {},
|
||||
agents: {},
|
||||
mcpServers: {},
|
||||
hooksConfigs: [],
|
||||
plugins: [],
|
||||
errors: [],
|
||||
};
|
||||
}
|
||||
|
||||
function createPluginConfig(): OhMyOpenCodeConfig {
|
||||
return {};
|
||||
}
|
||||
|
||||
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");
|
||||
});
|
||||
});
|
||||
@@ -9,6 +9,8 @@ import {
|
||||
import { loadBuiltinCommands } from "../features/builtin-commands";
|
||||
import {
|
||||
discoverConfigSourceSkills,
|
||||
loadGlobalAgentsSkills,
|
||||
loadProjectAgentsSkills,
|
||||
loadUserSkills,
|
||||
loadProjectSkills,
|
||||
loadOpencodeGlobalSkills,
|
||||
@@ -36,7 +38,9 @@ export async function applyCommandConfig(params: {
|
||||
opencodeGlobalCommands,
|
||||
opencodeProjectCommands,
|
||||
userSkills,
|
||||
globalAgentsSkills,
|
||||
projectSkills,
|
||||
projectAgentsSkills,
|
||||
opencodeGlobalSkills,
|
||||
opencodeProjectSkills,
|
||||
] = await Promise.all([
|
||||
@@ -49,7 +53,9 @@ export async function applyCommandConfig(params: {
|
||||
loadOpencodeGlobalCommands(),
|
||||
loadOpencodeProjectCommands(params.ctx.directory),
|
||||
includeClaudeSkills ? loadUserSkills() : Promise.resolve({}),
|
||||
includeClaudeSkills ? loadGlobalAgentsSkills() : Promise.resolve({}),
|
||||
includeClaudeSkills ? loadProjectSkills(params.ctx.directory) : Promise.resolve({}),
|
||||
includeClaudeSkills ? loadProjectAgentsSkills(params.ctx.directory) : Promise.resolve({}),
|
||||
loadOpencodeGlobalSkills(),
|
||||
loadOpencodeProjectSkills(params.ctx.directory),
|
||||
]);
|
||||
@@ -59,11 +65,13 @@ export async function applyCommandConfig(params: {
|
||||
...skillsToCommandDefinitionRecord(configSourceSkills),
|
||||
...userCommands,
|
||||
...userSkills,
|
||||
...globalAgentsSkills,
|
||||
...opencodeGlobalCommands,
|
||||
...opencodeGlobalSkills,
|
||||
...systemCommands,
|
||||
...projectCommands,
|
||||
...projectSkills,
|
||||
...projectAgentsSkills,
|
||||
...opencodeProjectCommands,
|
||||
...opencodeProjectSkills,
|
||||
...params.pluginComponents.commands,
|
||||
|
||||
Reference in New Issue
Block a user