Files
oh-my-opencode/src/tools/skill/description-formatter.ts
T
2026-04-04 01:27:51 +09:00

62 lines
1.8 KiB
TypeScript

import { TOOL_DESCRIPTION_NO_SKILLS, TOOL_DESCRIPTION_PREFIX } from "./constants"
import { sortByScopePriority } from "./scope-priority"
import type { SkillInfo } from "./types"
import type { CommandInfo } from "../slashcommand/types"
function formatSkillCommand(skill: SkillInfo): string {
const lines = [
" <command>",
` <name>/${skill.name}</name>`,
` <description>${skill.description}</description>`,
` <scope>${skill.scope}</scope>`,
]
if (skill.compatibility) {
lines.push(` <compatibility>${skill.compatibility}</compatibility>`)
}
lines.push(" </command>")
return lines.join("\n")
}
function formatSlashCommand(command: CommandInfo): string {
const argumentHint = typeof command.metadata.argumentHint === "string"
? command.metadata.argumentHint.trim()
: undefined
const lines = [
" <command>",
` <name>/${command.name}</name>`,
` <description>${command.metadata.description || "(no description)"}</description>`,
` <scope>${command.scope}</scope>`,
]
if (argumentHint) {
lines.push(` <argument>${argumentHint}</argument>`)
}
lines.push(" </command>")
return lines.join("\n")
}
export function formatCombinedDescription(skills: SkillInfo[], commands: CommandInfo[]): string {
if (skills.length === 0 && commands.length === 0) {
return TOOL_DESCRIPTION_NO_SKILLS
}
const availableItems = [
...sortByScopePriority(skills).map(formatSkillCommand),
...sortByScopePriority(commands).map(formatSlashCommand),
]
if (availableItems.length === 0) {
return TOOL_DESCRIPTION_PREFIX
}
return `${TOOL_DESCRIPTION_PREFIX}
<available_items>
Priority: project > user > opencode > builtin/plugin | Skills listed before commands
Invoke via: skill(name="item-name") - omit leading slash for commands.
${availableItems.join("\n")}
</available_items>`
}