fix(skills): match skills by install name in preview command

The preview command's selectSkill function only matched skills by
DisplayName() and Name. For plugins-convention skills, the install
hint outputs InstallName() (namespace/name), which matched neither -
DisplayName() includes a [plugins] prefix and Name is just the base
name. This caused 'skill not found' errors when users ran the
suggested preview command after install.

Add InstallName() as an additional match criterion so that namespaced
skill identifiers produced by the install hint are accepted.

Closes #13248

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Sam Morrow 2026-04-21 09:56:27 +02:00
parent 49d4747a81
commit 1160943af3
No known key found for this signature in database
2 changed files with 46 additions and 1 deletions

View file

@ -391,7 +391,7 @@ func isMarkdownFile(filePath string) bool {
func selectSkill(opts *PreviewOptions, skills []discovery.Skill) (discovery.Skill, error) {
if opts.SkillName != "" {
for _, s := range skills {
if s.DisplayName() == opts.SkillName || s.Name == opts.SkillName {
if s.DisplayName() == opts.SkillName || s.Name == opts.SkillName || s.InstallName() == opts.SkillName {
return s, nil
}
}

View file

@ -206,6 +206,51 @@ func TestPreviewRun(t *testing.T) {
},
wantStdout: "My Skill",
},
{
name: "preview plugins skill matched by install name",
tty: true,
opts: &PreviewOptions{
repo: ghrepo.New("owner", "repo"),
SkillName: "aws-common/aws-mcp-setup",
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("GET", "repos/owner/repo/releases/latest"),
httpmock.StringResponse(`{"tag_name": "v1.0.0"}`),
)
reg.Register(
httpmock.REST("GET", "repos/owner/repo/git/ref/tags/v1.0.0"),
httpmock.StringResponse(`{"object": {"sha": "abc123", "type": "commit"}}`),
)
reg.Register(
httpmock.REST("GET", "repos/owner/repo/git/trees/abc123"),
httpmock.StringResponse(`{
"sha": "abc123",
"truncated": false,
"tree": [
{"path": "plugins", "type": "tree", "sha": "tree-plugins"},
{"path": "plugins/aws-common", "type": "tree", "sha": "tree-awscommon"},
{"path": "plugins/aws-common/skills", "type": "tree", "sha": "tree-awsskills"},
{"path": "plugins/aws-common/skills/aws-mcp-setup", "type": "tree", "sha": "treeSHA3"},
{"path": "plugins/aws-common/skills/aws-mcp-setup/SKILL.md", "type": "blob", "sha": "blob789"}
]
}`),
)
reg.Register(
httpmock.REST("GET", "repos/owner/repo/git/trees/treeSHA3"),
httpmock.StringResponse(`{
"tree": [
{"path": "SKILL.md", "type": "blob", "sha": "blob789", "size": 50}
]
}`),
)
reg.Register(
httpmock.REST("GET", "repos/owner/repo/git/blobs/blob789"),
httpmock.StringResponse(`{"sha": "blob789", "content": "`+encodedContent+`", "encoding": "base64"}`),
)
},
wantStdout: "My Skill",
},
{
name: "skill not found",
tty: true,