skilldiscovery

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package skilldiscovery holds the per-agent registries (curated built-ins, install hints) and the keyword match helper that the `entire review` picker uses to discover review-adjacent skills.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DedupeByInvocation added in v0.9.0

func DedupeByInvocation(in []agent.DiscoveredSkill) []agent.DiscoveredSkill

DedupeByInvocation collapses entries sharing an invocation name, keeping the first occurrence. Plugins can ship a skill and a same-named wrapper that forwards to it; scan order decides which wins.

func DollarForm added in v0.9.0

func DollarForm(name, pluginName string) string

DollarForm is codex's invocation syntax: "$name" or "$plugin:name". This is the explicit "use this skill" token from codex's own injected skills catalog ("name a skill with $SkillName or plain text").

func IsEligible

func IsEligible(agentName string) bool

IsEligible reports whether the given agent has any registry entry — either a curated built-in or an install hint. The picker uses this (intersected with "hooks installed") to decide whether to show a section for the agent.

func Matches

func Matches(name, description string) bool

Matches reports whether the given skill invocation contains any review-adjacent keyword (case-insensitive) in its name.

We deliberately match on name only. Descriptions often contain words like "review" or "inspect" in non-review contexts — "review the plan", "inspect recent sessions", "review checkpoints" — which would pull in unrelated skills. Legitimate review skills either have the keyword in their name directly (e.g. /test-auditor, /superpowers:receiving-code-review) or live under a plugin whose prefix contains it (e.g. /pr-review-toolkit:silent-failure-hunter matches via "review" in "pr-review-toolkit").

The description parameter is retained for signature stability — callers still supply it so the picker can show descriptions — but it does not affect match decisions.

func ParseSkillFrontmatter added in v0.9.0

func ParseSkillFrontmatter(data []byte) (name, description string, err error)

ParseSkillFrontmatter extracts `name:` and `description:` from a minimal YAML frontmatter block — the tiny subset these SKILL.md / command / agent files use. Surrounding double-quotes are trimmed so `description: "foo"` returns `foo`.

func PickLatestVersion added in v0.9.0

func PickLatestVersion(entries []os.DirEntry) (string, bool)

PickLatestVersion returns the "newest" version directory name among entries:

  • If any entry parses as semver (with or without a leading "v"), pick the highest semver; non-semver entries are ignored when a semver exists.
  • Otherwise fall back to the lexicographic max of all directory names. This handles the "unknown" sentinel some plugins ship, and the opaque content-hash version dirs codex plugins use (e.g. "fef63ecf").

Returns ("", false) if no usable directory entry exists.

func ScanFlatMarkdownDir added in v0.9.0

func ScanFlatMarkdownDir(ctx context.Context, dir, pluginName string, invoke InvocationForm) []agent.DiscoveredSkill

ScanFlatMarkdownDir reads *.md files directly under dir (no nesting), parses their frontmatter for `description:`, and derives the invocation name from the filename (minus .md). Used by Claude Code for plugin/user commands and agents, whose frontmatter has no `name:` field. README.md is skipped.

func ScanPluginCache added in v0.9.0

func ScanPluginCache(ctx context.Context, root string, scanVersion func(versionRoot, pluginName string) []agent.DiscoveredSkill) []agent.DiscoveredSkill

ScanPluginCache walks <root>/<marketplace>/<plugin>/<version>/ and invokes scanVersion once per plugin, for the single version directory chosen by PickLatestVersion. The callback receives the chosen version root and the plugin name (used as the invocation namespace). Both Claude Code and codex use this same market/plugin/version cache layout; they differ only in which subdirectories under the version root they scan and their invocation form.

func ScanSkillsDir added in v0.9.0

func ScanSkillsDir(ctx context.Context, dir, pluginName string, invoke InvocationForm) []agent.DiscoveredSkill

ScanSkillsDir reads each <dir>/<name>/SKILL.md, parses its frontmatter, and emits a DiscoveredSkill (in invoke's form) when Matches() returns true. pluginName is the namespace ("" for un-namespaced user skills). Missing dirs yield nil — discovery is best-effort.

func SlashForm added in v0.9.0

func SlashForm(name, pluginName string) string

SlashForm is Claude Code's invocation syntax: "/name" or "/plugin:name".

Types

type CuratedSkill

type CuratedSkill struct {
	Name string
	Desc string
}

CuratedSkill is an entry in the curated per-agent built-in list. Name is the skill's invocation form (slash-prefixed); Desc is the picker-visible description.

func CuratedBuiltinsFor

func CuratedBuiltinsFor(agentName string) []CuratedSkill

CuratedBuiltinsFor returns the curated built-in list for agentName, or an empty slice if the agent is unknown. Callers must treat the return value as read-only.

type InstallHint

type InstallHint struct {
	Message     string
	ProvidesAny []string
}

InstallHint is a per-agent message shown in the "Install more" section of the picker. ProvidesAny lists the discovered skill names whose presence means "this plugin is already installed" — if any of those appear in the discovered set, the hint is suppressed.

When ProvidesAny is nil, the hint is always shown — use this for ecosystems where we can't predict plugin skill names (e.g. Gemini).

func ActiveInstallHintsFor

func ActiveInstallHintsFor(agentName string, discovered map[string]struct{}) []InstallHint

ActiveInstallHintsFor returns the subset of installHints[agentName] whose ProvidesAny does NOT intersect the discovered set. When ProvidesAny is nil, the hint is always active.

discovered is a set of skill names (map for O(1) membership); pass nil or an empty map when no skills have been discovered.

type InvocationForm added in v0.9.0

type InvocationForm func(name, pluginName string) string

InvocationForm builds an agent's invocation string for a discovered skill. The only thing that differs between agents is the prefix and namespace joiner: Claude Code uses slash form (`/name`, `/plugin:name`), codex uses dollar form (`$name`, `$plugin:name`) — the literal token a user types to invoke the skill in that CLI. Discovery emits Name already in this form so downstream prompt composition stays agent-agnostic and joins verbatim.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL