fix(skill): unify command listing format and trim verbose description
This commit is contained in:
parent
e70539fe5f
commit
17d3184e7a
@ -2,13 +2,8 @@ export const TOOL_NAME = "skill" as const
|
||||
|
||||
export const TOOL_DESCRIPTION_NO_SKILLS = "Load a skill or execute a slash command to get detailed instructions for a specific task. No skills are currently available."
|
||||
|
||||
export const TOOL_DESCRIPTION_PREFIX = `Load a skill or execute a slash command to get detailed instructions for a specific task.
|
||||
export const TOOL_DESCRIPTION_PREFIX = `Load a skill or execute a command to get detailed instructions for a specific task.
|
||||
|
||||
Skills and commands provide specialized knowledge and step-by-step guidance.
|
||||
Use this when a task matches an available skill's or command's description.
|
||||
|
||||
**How to use:**
|
||||
- Call with a skill name: name='code-review'
|
||||
- Call with a command name (without leading slash): name='publish'
|
||||
- The tool will return detailed instructions with your context applied.
|
||||
`
|
||||
|
||||
@ -4,6 +4,7 @@ import * as fs from "node:fs"
|
||||
import { createSkillTool } from "./tools"
|
||||
import { SkillMcpManager } from "../../features/skill-mcp-manager"
|
||||
import type { LoadedSkill } from "../../features/opencode-skill-loader/types"
|
||||
import type { CommandInfo } from "../slashcommand/types"
|
||||
import type { Tool as McpTool } from "@modelcontextprotocol/sdk/types.js"
|
||||
|
||||
const originalReadFileSync = fs.readFileSync.bind(fs)
|
||||
@ -105,6 +106,61 @@ describe("skill tool - synchronous description", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("skill tool - command listing format", () => {
|
||||
it("uses XML format for commands in description", () => {
|
||||
// given
|
||||
const commands: CommandInfo[] = [
|
||||
{
|
||||
name: "publish",
|
||||
path: "/test/commands/publish",
|
||||
metadata: { name: "publish", description: "Publish to npm", argumentHint: "<patch|minor|major>" },
|
||||
scope: "opencode-project",
|
||||
},
|
||||
{
|
||||
name: "commit",
|
||||
path: "/test/commands/commit",
|
||||
metadata: { name: "commit", description: "Commits changes" },
|
||||
scope: "builtin",
|
||||
},
|
||||
]
|
||||
|
||||
// when
|
||||
const tool = createSkillTool({ skills: [], commands })
|
||||
|
||||
// then
|
||||
expect(tool.description).toContain("<available_commands>")
|
||||
expect(tool.description).toContain("</available_commands>")
|
||||
expect(tool.description).toContain("<command>")
|
||||
expect(tool.description).toContain("<name>/publish <patch|minor|major></name>")
|
||||
expect(tool.description).toContain("<description>Publish to npm</description>")
|
||||
expect(tool.description).toContain("<scope>opencode-project</scope>")
|
||||
expect(tool.description).toContain("<name>/commit</name>")
|
||||
expect(tool.description).toContain("<scope>builtin</scope>")
|
||||
})
|
||||
|
||||
it("uses XML format for both skills and commands together", () => {
|
||||
// given
|
||||
const loadedSkills = [createMockSkill("test-skill")]
|
||||
const commands: CommandInfo[] = [
|
||||
{
|
||||
name: "deploy",
|
||||
path: "/test/commands/deploy",
|
||||
metadata: { name: "deploy", description: "Deploy app" },
|
||||
scope: "user",
|
||||
},
|
||||
]
|
||||
|
||||
// when
|
||||
const tool = createSkillTool({ skills: loadedSkills, commands })
|
||||
|
||||
// then
|
||||
expect(tool.description).toContain("<available_skills>")
|
||||
expect(tool.description).toContain("<available_commands>")
|
||||
expect(tool.description).toContain("<command>")
|
||||
expect(tool.description).toContain("<name>/deploy</name>")
|
||||
})
|
||||
})
|
||||
|
||||
describe("skill tool - agent restriction", () => {
|
||||
it("allows skill without agent restriction to any agent", async () => {
|
||||
// given
|
||||
|
||||
@ -48,11 +48,18 @@ function formatCombinedDescription(skills: SkillInfo[], commands: CommandInfo[])
|
||||
}
|
||||
|
||||
if (commands.length > 0) {
|
||||
const commandLines = commands.map(cmd => {
|
||||
const commandsXml = commands.map(cmd => {
|
||||
const hint = cmd.metadata.argumentHint ? ` ${cmd.metadata.argumentHint}` : ""
|
||||
return ` - /${cmd.name}${hint}: ${cmd.metadata.description || "(no description)"} (${cmd.scope})`
|
||||
const parts = [
|
||||
" <command>",
|
||||
` <name>/${cmd.name}${hint}</name>`,
|
||||
` <description>${cmd.metadata.description || "(no description)"}</description>`,
|
||||
` <scope>${cmd.scope}</scope>`,
|
||||
" </command>",
|
||||
]
|
||||
return parts.join("\n")
|
||||
}).join("\n")
|
||||
lines.push(`\n<available_commands>\n${commandLines}\n</available_commands>`)
|
||||
lines.push(`\n<available_commands>\n${commandsXml}\n</available_commands>`)
|
||||
}
|
||||
|
||||
return TOOL_DESCRIPTION_PREFIX + lines.join("")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user