skills

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package skills syncs Port catalog skills to local AI tool directories. Catalog reads and writes go through internal/api skills routes.

Index

Constants

View Source
const (
	SkillLocationGlobal  SkillLocation = "global"
	SkillLocationProject SkillLocation = "project"

	NoGroupDir    = "_skills_without_group"
	PortSkillsDir = "port"
)
View Source
const ExcludeSkillFiles = "files"

ExcludeSkillFiles is the exclude query value for omitting file content.

Variables

This section is empty.

Functions

func ApplySyncDefaults added in v0.3.1

func ApplySyncDefaults(cfg *config.SkillsConfig)

ApplySyncDefaults fills skill selection when the user has not run 'port skills init'. Targets must be configured by init or passed to sync.

func BoolPtr added in v0.3.1

func BoolPtr(v bool) *bool

BoolPtr returns a bool pointer for optional skills API query flags.

func DiscoverSkillRoots added in v0.3.1

func DiscoverSkillRoots(path string) ([]string, error)

DiscoverSkillRoots returns skill directory paths under path. If path contains SKILL.md at its root, returns path. Otherwise searches descendants for directories whose root contains SKILL.md. Descent stops at each skill directory (contents are not searched further).

func GroupName

func GroupName(groups []SkillGroup, groupID string) string

GroupName resolves the display name for a group, falling back to its identifier.

func GroupSelectionFromCatalog added in v0.3.1

func GroupSelectionFromCatalog(groups []api.SkillGroupAtLatestVersion, selected []string) (include, exclude []string)

GroupSelectionFromCatalog computes include/exclude deltas vs team-owned groups.

func GroupSyncIntents added in v0.3.1

func GroupSyncIntents(groups []api.SkillGroupAtLatestVersion, cfg *config.SkillsConfig, initialSelected []string) map[string]GroupSyncIntent

GroupSyncIntents maps each catalog group to display/sync metadata for interactive init.

func InitialSelectedGroupIDs added in v0.3.1

func InitialSelectedGroupIDs(groups []api.SkillGroupAtLatestVersion, cfg *config.SkillsConfig) []string

InitialSelectedGroupIDs returns multiselect defaults from saved config when present, else team-owned groups.

func InitialUngroupedSelection added in v0.3.1

func InitialUngroupedSelection(cfg *config.SkillsConfig) (selectAll bool, skillIDs []string)

InitialUngroupedSelection returns saved ungrouped sync defaults for interactive prompts.

func InstallHooks

func InstallHooks(targets []HookTarget, globalRoot, repoRoot string) error

InstallHooks writes (or merges) the hook configuration for each target.

func NormalizeSkillLocation added in v0.3.1

func NormalizeSkillLocation(location string) (string, error)

NormalizeSkillLocation validates and normalizes a skill location value. Empty input defaults to global.

func PreselectedGroupIDs added in v0.3.1

func PreselectedGroupIDs(groups []api.SkillGroupAtLatestVersion) []string

PreselectedGroupIDs returns group identifiers that match the user's teams.

func ResolveTargetNames

func ResolveTargetNames(savedPaths []string, targets []HookTarget) []string

ResolveTargetNames maps saved target paths back to their HookTarget names. It matches by checking suffixes (Dir, XDGDir) and exact env-override values.

func TargetPaths

func TargetPaths(targets []HookTarget, globalRoot, repoRoot string) []string

TargetPaths resolves the absolute paths for all hook targets. Global targets are rooted at globalRoot (home dir); repo-scoped targets are rooted at repoRoot (cwd).

func UnloadSkillFromTargets added in v0.3.1

func UnloadSkillFromTargets(identifier string, globalTargets, projectDirs []string) error

UnloadSkillFromTargets removes local copies of a skill under skills/port/ for every target.

func WriteSkills

func WriteSkills(skills []Skill, groups []SkillGroup, globalTargets []string, projectDirs []string) error

WriteSkills writes SKILL.md files (plus references, assets, scripts, and additional files) for each skill, routing each one based on its Location property:

  • SkillLocationGlobal → written into every dir in globalTargets
  • SkillLocationProject → written into the matching tool sub-directory inside every projectDir (e.g. <projectDir>/.agents/skills/port/…)

Types

type AddSkillsOptions added in v0.2.13

type AddSkillsOptions struct {
	Groups  []string
	Skills  []string
	Targets []HookTarget
}

AddSkillsOptions holds options for incrementally extending the saved selection.

type AddSkillsResult added in v0.2.13

type AddSkillsResult struct {
	Merge       MergeSelectionResult
	Sync        *LoadSkillsResult
	NewTargets  []string
	InstalledOK bool
}

AddSkillsResult summarises an add operation.

type ClearSkillsResult

type ClearSkillsResult struct {
	DeletedTargets []string
	SkippedTargets []string
}

ClearSkillsResult summarises what was deleted.

type FetchSkillsQuery added in v0.3.1

type FetchSkillsQuery struct {
	SkillIdentifiers   []string
	IncludeGroups      []string
	ExcludeGroups      []string
	TeamsDefault       *bool
	Exclude            []string
	ExcludeFiles       bool
	IncludeUngrouped   bool
	IncludeUnpublished bool
}

FetchSkillsQuery optional filters for loading the sync catalog.

type FetchedSkills

type FetchedSkills struct {
	Skills []Skill
	Groups []SkillGroup
}

FetchedSkills contains the skill catalog from Port.

func CatalogFromAPI added in v0.3.1

func CatalogFromAPI(resp *api.GroupedSkillsResponse) *FetchedSkills

CatalogFromAPI maps the grouped skills API response to FetchedSkills.

func FetchSkillsFromAPI added in v0.3.1

func FetchSkillsFromAPI(ctx context.Context, client *api.Client, query FetchSkillsQuery) (*FetchedSkills, error)

FetchSkillsFromAPI loads the skill catalog.

type GroupSkillCount added in v0.3.1

type GroupSkillCount struct {
	Identifier string
	Title      string
	SkillCount int
	Skills     []InitSkillSummary
}

GroupSkillCount is one skill group with its member skills for init overview.

type GroupSyncIntent added in v0.3.1

type GroupSyncIntent struct {
	TeamOwned     bool
	SavedInclude  bool
	SavedExclude  bool
	InitiallySync bool
}

GroupSyncIntent describes team ownership, saved include/exclude deltas, and the initial checkbox state.

type HookTarget

type HookTarget struct {
	Name           string
	Dir            string
	ProjectDir     string
	Format         hookFormat
	RepoScoped     bool
	Note           string
	EnvOverride    string
	XDGDir         string
	HookSubDir     string
	LegacyHookDirs []string
	// SkillsOnly: sync skills under {Dir}/skills/port/ but do not install session hooks.
	// Used for cross-platform .agents (agentskills.io) and for default sync without init.
	SkillsOnly bool
}

HookTarget describes one AI tool directory and how to write its hook. When RepoScoped is true the hook is installed relative to the repository root (cwd) rather than the user's home directory.

ProjectDir, when set, overrides Dir for project-scoped skill placement when mapping global hook target paths to per-repo tool directories (see extractProjectDirs). Most tools leave this empty so Dir is used.

HookSubDir, when set, is appended to the resolved base directory so hooks are written to {base}/{HookSubDir}/ (e.g. GitHub Copilot uses base <repo>/.github and HookSubDir "hooks" for <repo>/.github/hooks/hooks.json). Skills are always written under {base}/skills/port/ (not under HookSubDir).

LegacyHookDirs lists extra directories under the user's home directory where older CLI versions may have installed hooks for this tool. RemoveHooks cleans those paths in addition to the primary hook directory.

EnvOverride names an environment variable (e.g. CURSOR_CONFIG_DIR) that, when set, is used as the absolute directory instead of the default. XDGDir names the directory under $XDG_CONFIG_HOME (e.g. "cursor") used on Linux/BSD when XDG_CONFIG_HOME is set and EnvOverride is not.

func AgentsHookTarget added in v0.3.1

func AgentsHookTarget() HookTarget

AgentsHookTarget is the cross-platform skills directory per agentskills.io (~/.agents/skills/ and <project>/.agents/skills/). Port writes under skills/port/.

func DefaultHookTargets

func DefaultHookTargets() []HookTarget

DefaultHookTargets returns the list of supported AI tool directories.

func DefaultSyncTargets added in v0.3.1

func DefaultSyncTargets() []HookTarget

DefaultSyncTargets returns tool directories used when syncing without a prior init.

type InitCatalogStats added in v0.3.1

type InitCatalogStats struct {
	GroupCount     int
	Groups         []GroupSkillCount
	Ungrouped      []InitSkillSummary
	UngroupedCount int
}

InitCatalogStats summarizes the published skills catalog for interactive init.

func InitCatalogStatsFrom added in v0.3.1

func InitCatalogStatsFrom(catalogGroups []api.SkillGroupAtLatestVersion, catalog *FetchedSkills) InitCatalogStats

InitCatalogStatsFrom builds group and ungrouped summaries from a metadata-only catalog (GET /v1/skills?exclude=files) and the group list from GET /v1/skills/groups.

type InitOptions

type InitOptions struct {
	Targets []HookTarget
}

InitOptions holds options for the init operation.

type InitResult

type InitResult struct {
	InstalledTargets []string
}

InitResult holds the result of an init operation.

type InitSkillSummary added in v0.3.1

type InitSkillSummary struct {
	Identifier string
	Title      string
	Version    string
}

InitSkillSummary is one published skill row for the interactive init catalog overview.

type LoadSkillsOptions

type LoadSkillsOptions struct {
	SelectAll          bool
	SelectAllGroups    bool
	SelectAllUngrouped bool
	SelectedGroups     []string
	SelectedSkills     []string
	IncludeGroups      []string
	ExcludeGroups      []string
	TeamGroupDefaults  bool
	// Fetched is an optional pre-fetched catalog. When set, LoadSkills skips the
	// FetchSkills API call and uses this data directly, avoiding duplicate
	// network requests when the caller already has the catalog in hand (e.g.,
	// the init command fetches once for prompts and reuses the same data for sync).
	Fetched *FetchedSkills
	// ReplaceSelection overwrites saved group/skill selection from opts instead of
	// only updating when opts carry selection fields (used by port skills select).
	ReplaceSelection bool
	// ExcludeLegacySkills omits legacy blueprint `skill` entities from the catalog fetch.
	ExcludeLegacySkills bool
	// IncludeInternalSkills includes Port built-in registry skills (excluded by default).
	IncludeInternalSkills bool
	// TargetOverrides writes to these target directories for this sync only.
	TargetOverrides []string
	// ProjectDirOverrides writes project-scoped skills under these project dirs
	// for this sync only.
	ProjectDirOverrides []string
	// NoSave prevents sync-only options from being written to config.yaml.
	NoSave bool
}

LoadSkillsOptions holds options for the load-skills operation.

type LoadSkillsResult

type LoadSkillsResult struct {
	GroupCount    int
	SkillCount    int
	TargetCount   int
	TargetResults []TargetResult
}

LoadSkillsResult summarises what was written.

type MergeSelectionResult added in v0.2.13

type MergeSelectionResult struct {
	AddedGroups   []string
	AddedSkills   []string
	SkippedGroups []string
	SkippedSkills []string
}

MergeSelectionResult reports what was merged into the skills config.

func MergeSelection added in v0.2.13

func MergeSelection(cfg *config.SkillsConfig, fetched *FetchedSkills, addGroups, addSkills []string) (MergeSelectionResult, error)

MergeSelection appends group and skill identifiers to cfg without replacing the existing selection. Unknown identifiers return an error. Items already covered by the current selection are listed in Skipped*.

func (MergeSelectionResult) HasChanges added in v0.2.13

func (r MergeSelectionResult) HasChanges() bool

HasChanges reports whether any new groups or skills were added.

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module orchestrates hook installation and skill syncing for Port AI skills.

func NewModule

func NewModule(token *auth.Token, orgConfig *config.OrganizationConfig, configManager *config.ConfigManager) *Module

func (*Module) AddSkills added in v0.2.13

func (m *Module) AddSkills(ctx context.Context, opts AddSkillsOptions) (*AddSkillsResult, error)

AddSkills merges new groups/skills (and optionally new hook targets) into the saved configuration and syncs skills to disk.

func (*Module) ClearSkills

func (m *Module) ClearSkills() (*ClearSkillsResult, error)

ClearSkills removes the Port skills directory ({target}/skills/port/) from every configured AI tool target and project directory. Targets where the directory does not exist are silently skipped.

func (*Module) ConfigureSelection added in v0.3.1

func (m *Module) ConfigureSelection(opts LoadSkillsOptions) error

ConfigureSelection persists the selected skill groups and ungrouped skills without downloading or writing skill files.

func (*Module) FetchGroupsForInit added in v0.3.1

func (m *Module) FetchGroupsForInit(ctx context.Context) ([]api.SkillGroupAtLatestVersion, error)

FetchGroupsForInit fetches all skill groups with team ownership for the init selection UI.

func (*Module) FetchSkill added in v0.3.1

func (m *Module) FetchSkill(ctx context.Context, identifier string) (Skill, error)

FetchSkill loads one published skill.

func (*Module) FetchSkills

func (m *Module) FetchSkills(ctx context.Context) (*FetchedSkills, error)

func (*Module) FetchSkillsMetadata added in v0.3.1

func (m *Module) FetchSkillsMetadata(ctx context.Context) (*FetchedSkills, error)

FetchSkillsMetadata loads the catalog without file content for prompts and selection bookkeeping. Use LoadSkills for the write-to-disk path.

func (*Module) FetchSkillsWithQuery added in v0.3.1

func (m *Module) FetchSkillsWithQuery(ctx context.Context, query FetchSkillsQuery) (*FetchedSkills, error)

FetchSkillsWithQuery loads the sync catalog using explicit skills API query parameters.

func (*Module) Init

func (m *Module) Init(ctx context.Context, opts InitOptions) (*InitResult, error)

Init installs hooks into the user's home directory for all selected targets, registers the current working directory as a project dir for project-scoped skills, and persists the configuration.

func (*Module) LoadSkills

func (m *Module) LoadSkills(ctx context.Context, opts LoadSkillsOptions) (*LoadSkillsResult, error)

LoadSkills fetches skills from Port and writes them to the appropriate targets. Skills with location="project" are written to the current working directory; all other skills are written to the configured global AI tool directories.

func (*Module) PreviewSkills added in v0.3.1

func (m *Module) PreviewSkills(ctx context.Context, opts PreviewSkillsOptions) (*api.GroupedSkillsResponse, error)

PreviewSkills returns the grouped skills response matching the saved sync configuration. It never downloads file content. Pass All=true to bypass saved filters and show everything.

func (*Module) PublishSkill added in v0.3.1

func (m *Module) PublishSkill(ctx context.Context, identifier string) (*api.SkillVersionWriteResponse, error)

PublishSkill sets the active version to the latest semver in Port.

func (*Module) RegisterTargets added in v0.3.1

func (m *Module) RegisterTargets(ctx context.Context, targets []HookTarget) error

RegisterTargets saves hook target paths without installing hooks.

func (*Module) Remove

func (m *Module) Remove() (*RemoveResult, error)

Remove uninstalls hooks, local synced skills, and clears skills config:

  • Port hook entries from hooks.json / settings.json (other hooks preserved)
  • Local skills directories (skills/port/)
  • The skills section from ~/.port/config.yaml

func (*Module) RemoveSkills added in v0.2.15

func (m *Module) RemoveSkills(ctx context.Context, opts RemoveSkillsOptions) (*RemoveSkillsResult, error)

RemoveSkills drops groups/skills and/or hook targets from the saved configuration. Targets have their hooks uninstalled and their synced skills/port/ directories deleted; remaining skills are re-synced so any pruned items are removed from disk on the remaining targets.

func (*Module) SearchSkills added in v0.3.1

func (m *Module) SearchSkills(ctx context.Context, query api.SearchSkillsQuery) ([]api.SkillCatalogEntry, error)

SearchSkills finds skills by identifier or title (GET /skills/search).

func (*Module) Status

func (m *Module) Status() (*StatusResult, error)

Status returns the current skills configuration state.

func (*Module) UnpublishSkill added in v0.3.1

func (m *Module) UnpublishSkill(ctx context.Context, identifier string) error

UnpublishSkill clears the active version in Port.

func (*Module) UploadSkillFromFolder added in v0.3.1

func (m *Module) UploadSkillFromFolder(ctx context.Context, folder string, opts PackSkillFolderOptions, writeOpts UploadSkillWriteOptions) (*api.SkillVersionWriteResponse, error)

UploadSkillFromFolder uploads a skill via POST /skills/upload.

func (*Module) UploadSkillFromPack added in v0.3.1

func (m *Module) UploadSkillFromPack(ctx context.Context, pack *SkillFolderPack, folderBase string, writeOpts UploadSkillWriteOptions) (*api.SkillVersionWriteResponse, error)

UploadSkillFromPack uploads a packed skill folder via POST /skills/upload.

func (*Module) UploadSkillsBatch added in v0.3.1

func (m *Module) UploadSkillsBatch(ctx context.Context, packs []SkillPackWithFolder, writeOpts UploadSkillWriteOptions) (*api.BatchUploadSkillsResponse, error)

UploadSkillsBatch uploads multiple skills via POST /skills/upload/batch.

type PackSkillFolderOptions added in v0.3.1

type PackSkillFolderOptions struct {
	Identifier  string
	Title       string
	Description string
	Location    string
}

PackSkillFolderOptions configures reading a skill directory from disk.

type PreviewSkillsOptions added in v0.3.1

type PreviewSkillsOptions struct {
	All                bool
	IncludeUnpublished bool
}

PreviewSkillsOptions controls what skills are returned by PreviewSkills.

type RemoveHooksResult

type RemoveHooksResult struct {
	RemovedFrom []string
	Skipped     []string
}

RemoveHooksResult reports what was changed per target.

func RemoveHooks

func RemoveHooks(targets []HookTarget, globalRoot, repoRoot string, savedSkillRoots []string) (*RemoveHooksResult, error)

RemoveHooks removes only the Port hook entries from each target, preserving any other hooks. Empty hook files are deleted entirely. savedSkillRoots should be config.SkillsConfig.Targets so repo-scoped hooks (GitHub Copilot) are found even when repoRoot is not the repository where hooks were installed. Pass nil to only use repoRoot for repo-scoped targets.

type RemoveResult

type RemoveResult struct {
	HooksResult  *RemoveHooksResult
	SkillsResult *ClearSkillsResult
}

RemoveResult summarises what was removed by a full skills/hooks uninstall.

type RemoveSelectionResult added in v0.2.15

type RemoveSelectionResult struct {
	RemovedGroups []string
	RemovedSkills []string
	SkippedGroups []string
	SkippedSkills []string
	// Materialized is true when a SelectAll* flag was expanded into explicit
	// lists to enable removal. Callers should surface this so users know
	// future Port-side additions will no longer auto-sync.
	Materialized bool
}

RemoveSelectionResult reports what was removed from the skills config.

func RemoveSelection added in v0.2.15

func RemoveSelection(cfg *config.SkillsConfig, fetched *FetchedSkills, removeGroups, removeSkills []string) (RemoveSelectionResult, error)

RemoveSelection drops group and skill identifiers from cfg. Items not currently in the selection are reported in Skipped*. Unknown identifiers return an error. If cfg uses any SelectAll* flag, the selection is materialized into explicit lists first so individual items can be removed.

func (RemoveSelectionResult) HasChanges added in v0.2.15

func (r RemoveSelectionResult) HasChanges() bool

HasChanges reports whether any group or skill was removed.

type RemoveSkillsOptions added in v0.2.15

type RemoveSkillsOptions struct {
	Groups  []string
	Skills  []string
	Targets []HookTarget
}

RemoveSkillsOptions holds options for removing items from the saved selection.

type RemoveSkillsResult added in v0.2.15

type RemoveSkillsResult struct {
	Remove         RemoveSelectionResult
	Sync           *LoadSkillsResult
	RemovedTargets []string
}

RemoveSkillsResult summarises a remove operation.

type Skill

type Skill struct {
	Identifier  string
	Title       string
	Description string
	Version     string
	GroupIDs    []string
	Location    SkillLocation
	Files       []SkillFile
}

Skill is a catalog skill ready to sync to disk.

func AvailableSkillsToAdd added in v0.2.13

func AvailableSkillsToAdd(cfg *config.SkillsConfig, fetched *FetchedSkills) []Skill

AvailableSkillsToAdd returns skills not yet covered by the selection.

func FilterSkills

func FilterSkills(fetched *FetchedSkills, selectAll, selectAllGroups, selectAllUngrouped bool, selectedGroups, selectedSkills []string, serverFilteredGroups bool) []Skill

FilterSkills returns skills matching the provided selection criteria.

func RemovableSkills added in v0.2.15

func RemovableSkills(cfg *config.SkillsConfig, fetched *FetchedSkills) []Skill

RemovableSkills returns skills currently in the user's explicit selection (cfg.SelectedSkills), plus any ungrouped optional skills covered by SelectAll / SelectAllUngrouped. Skills selected only via their group cannot be removed individually — the group must be removed instead.

func UngroupedSkills added in v0.3.1

func UngroupedSkills(fetched *FetchedSkills) []Skill

UngroupedSkills returns skills that are not members of any group in the catalog.

type SkillFile

type SkillFile struct {
	Path    string
	Content string
}

SkillFile is one file in a skill directory tree.

type SkillFolderPack added in v0.3.1

type SkillFolderPack struct {
	Identifier  string
	Title       string
	Description string
	Location    string
	Files       []api.SkillFileInput
}

SkillFolderPack is the parsed content of a local skill directory.

func PackSkillFolder added in v0.3.1

func PackSkillFolder(dir string, opts PackSkillFolderOptions) (*SkillFolderPack, error)

PackSkillFolder reads all files under dir into Port API file inputs. The folder must contain SKILL.md at its root. Identifier defaults to the directory name when opts.Identifier is empty.

type SkillGroup

type SkillGroup struct {
	Identifier       string
	Title            string
	MatchesUserTeams bool
	SkillIDs         []string
}

SkillGroup is a skill group from the catalog.

func AvailableGroupsToAdd added in v0.2.13

func AvailableGroupsToAdd(cfg *config.SkillsConfig, fetched *FetchedSkills) []SkillGroup

AvailableGroupsToAdd returns optional groups not yet in the user's selection.

func RemovableGroups added in v0.2.15

func RemovableGroups(cfg *config.SkillsConfig, fetched *FetchedSkills) []SkillGroup

RemovableGroups returns groups currently in the user's selection, virtually expanding SelectAll* coverage so users can remove any group that is in effect.

type SkillLocation

type SkillLocation string

SkillLocation controls where a skill is written on disk.

type SkillPackWithFolder added in v0.3.1

type SkillPackWithFolder struct {
	Pack       *SkillFolderPack
	FolderBase string
}

SkillPackWithFolder pairs a packed skill with its source folder basename.

type StatusResult

type StatusResult struct {
	Targets            []string
	ProjectDirs        []string
	SelectAll          bool
	SelectAllGroups    bool
	SelectAllUngrouped bool
	TeamGroupDefaults  bool
	IncludeGroups      []string
	ExcludeGroups      []string
	SelectedGroups     []string
	SelectedSkills     []string
	LastSyncedAt       string
}

StatusResult contains the data surfaced by `port skills status`.

type TargetResult

type TargetResult struct {
	Path       string
	GroupCount int
	SkillCount int
	IsProject  bool
	// GitHubCopilotRepo is true for a unified row under <repo>/.github/skills/port:
	// Port catalog "global" and "project" skills are both written there only, not
	// to a separate home-directory global path — avoid labeling as plain "global".
	GitHubCopilotRepo bool
}

TargetResult holds the sync result for a single AI tool directory.

type UploadSkillWriteOptions added in v0.3.1

type UploadSkillWriteOptions struct {
	Publish  bool
	GroupIDs []string

	VersionBump api.VersionBump
}

UploadSkillWriteOptions controls version creation when uploading skills.

Jump to

Keyboard shortcuts

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