Every SKILL.md across every agentic-CLI harness on your machine — in one TUI, in one keystroke.
curl -sSL https://heidihowilson.github.io/skillscope/install.sh | sh
Matrix view: rows = skills, columns = scope, dots = harnesses that have the skill at that scope.
Claude Code, Codex CLI, Cursor, OpenCode, Antigravity — each with their real brand colors and correct scope conventions.
Matrix (default), Tree (scope-grouped with harness dots), Diff (LCS-aligned master/detail).
Copy / move / delete refuse read-only scopes and never follow symlinks. Delete requires retyping the skill name.
Adding a new harness or view is one self-registering Go file. The core never has to know about it.
--json dumps every skill as a single versioned JSON document for scripting and CI checks.
No CGO. Linux / macOS / Windows. Ships pre-built via GitHub Releases on every tag.
brew install heidihowilson/tap/skillscope
scoop bucket add heidihowilson https://github.com/heidihowilson/scoop-bucket
scoop install skillscope
go install github.com/heidihowilson/skillscope/cmd/skillscope@latest
Pre-built binaries also live on the Releases page. Pin a version with the curl-pipe installer via SKILLSCOPE_VERSION=v0.2.0.
Use the same channel you installed from. Check what you're running with skillscope --version.
| curl-pipe | curl -sSL https://heidihowilson.github.io/skillscope/install.sh | sh |
| Homebrew | brew update && brew upgrade skillscope |
| Scoop | scoop update skillscope |
| go install | go install github.com/heidihowilson/skillscope/cmd/skillscope@latest |
| q · Ctrl+C | quit |
| ? | help overlay |
| / | fuzzy search |
| Esc | close preview / clear filter |
| 1–9 | jump to view |
| v · V | cycle views |
| f | cycle harness filter |
| s | cycle scope filter |
| g | toggle "shadowed only" |
| R | re-scan filesystem |
| p | preview: off → raw → rendered |
| e | open in $EDITOR |
| c | copy to scope (numbered picker, then 1–9) |
| m | move to scope |
| d | delete (re-type skill name to confirm) |
| y | yank skill path |
The plugin surface is the whole point. Adding a harness is one self-registering file:
package myharness
import (
"path/filepath"
"github.com/charmbracelet/lipgloss"
"github.com/heidihowilson/skillscope/internal/harness"
)
type h struct{}
func (h) ID() string { return "myharness" }
func (h) Name() string { return "My Harness" }
func (h) Color() lipgloss.Color { return lipgloss.Color("#FF66CC") }
func (h) Scopes(ctx harness.Context) []harness.Scope {
scopes := []harness.Scope{{
Harness: "myharness", Kind: harness.User,
Path: filepath.Join(ctx.HomeDir, ".myharness", "skills"),
}}
if ctx.RepoRoot != "" {
scopes = append(scopes, harness.Scope{
Harness: "myharness", Kind: harness.Project,
Path: filepath.Join(ctx.RepoRoot, ".myharness", "skills"),
})
}
return scopes
}
func init() { harness.Register(h{}) }
Add a blank-import line in cmd/skillscope/main.go and it shows up in the tab bar. See CONTRIBUTING.md for adding a new view.
Agentic-CLI tools all converged on the same pattern: a SKILL.md file with YAML frontmatter living in a directory under ~/.<tool>/skills/ or ./.<tool>/skills/. The trouble is, once you use more than one tool, you have skills sprawled across 5 different conventions and you stop knowing what you have where. skillscope reads all of them, in one place, and lets you move things between scopes without leaving the terminal.