Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions internal/cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ var listCmd = &cobra.Command{
Short: "List available resources",
Long: `List available resources of a given type.

Resource types: skills, agents, instructions, prompts
Resource types: skills, agents, instructions, prompts, targets, registries

Examples:
positive-vibes list skills
positive-vibes list skills --registry=embedded
positive-vibes list skills --installed-only
positive-vibes list skills --json
positive-vibes list agents
positive-vibes list instructions`,
positive-vibes list instructions
positive-vibes list targets
positive-vibes list registries`,
Args: cobra.ExactArgs(1),
ValidArgsFunction: makeValidArgsFunction(""),
RunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -51,6 +53,10 @@ Examples:
listInstructionsRun(merged)
case ResourcePrompts:
listPromptsRun(merged)
case ResourceTargets:
listTargetsRun(merged)
case ResourceRegistries:
listRegistriesRun(merged)
}
return nil
},
Expand Down Expand Up @@ -105,6 +111,28 @@ func listPromptsRun(merged *manifest.Manifest) {
fmt.Print(formatResourceList(ResourcePrompts, items))
}

func listTargetsRun(merged *manifest.Manifest) {
items := collectAvailableTargets(merged)

if listJSON {
fmt.Println(formatResourceListJSON(ResourceTargets, items))
return
}

fmt.Print(formatResourceList(ResourceTargets, items))
}

func listRegistriesRun(merged *manifest.Manifest) {
items := collectAvailableRegistries(merged)

if listJSON {
fmt.Println(formatResourceListJSON(ResourceRegistries, items))
return
}

fmt.Print(formatResourceList(ResourceRegistries, items))
}

func init() {
listCmd.Flags().StringVar(&listRegistry, "registry", "", "filter by registry name (skills only)")
listCmd.Flags().BoolVar(&listInstalledOnly, "installed-only", false, "show only installed resources (skills only)")
Expand Down
58 changes: 58 additions & 0 deletions internal/cli/skills_command_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"io"
"os"
"path/filepath"
"strings"
"testing"

Expand Down Expand Up @@ -79,6 +80,63 @@ func TestRemoveSkillsRun_PrintsMutationReportOnPartialFailure(t *testing.T) {
}
}

func TestListCmd_TargetsProducesOutput(t *testing.T) {
projectDir = t.TempDir()
t.Cleanup(func() { projectDir = "." })

manifestPath := filepath.Join(projectDir, "vibes.yaml")
if err := os.WriteFile(manifestPath, []byte("targets: [\"opencode\"]\n"), 0o644); err != nil {
t.Fatalf("write manifest: %v", err)
}

stdout, stderr := captureStdoutStderr(t, func() {
err := listCmd.RunE(listCmd, []string{"targets"})
if err != nil {
t.Fatalf("list targets run error: %v", err)
}
})

if !strings.Contains(stdout, "Targets:") {
t.Fatalf("stdout = %q, want targets list output", stdout)
}
if strings.TrimSpace(stderr) != "" {
t.Fatalf("stderr = %q, expected empty stderr", stderr)
}
}

func TestListCmd_RegistriesProducesOutput(t *testing.T) {
projectDir = t.TempDir()
t.Cleanup(func() { projectDir = "." })

manifestPath := filepath.Join(projectDir, "vibes.yaml")
content := `targets: ["opencode"]
registries:
- name: demo
url: https://example.com/demo.git
ref: main
`
if err := os.WriteFile(manifestPath, []byte(content), 0o644); err != nil {
t.Fatalf("write manifest: %v", err)
}

stdout, stderr := captureStdoutStderr(t, func() {
err := listCmd.RunE(listCmd, []string{"registries"})
if err != nil {
t.Fatalf("list registries run error: %v", err)
}
})

if !strings.Contains(stdout, "Registries:") {
t.Fatalf("stdout = %q, want registries list output", stdout)
}
if !strings.Contains(stdout, "demo") {
t.Fatalf("stdout = %q, want registry name", stdout)
}
if strings.TrimSpace(stderr) != "" {
t.Fatalf("stderr = %q, expected empty stderr", stderr)
}
}

func captureStdoutStderr(t *testing.T, run func()) (string, string) {
t.Helper()

Expand Down