skills

package
v0.41.2 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package skills is the AI agent skills service (spec/features/ai-agent-skills, capabilities 20 and 21): the two Agent Skills embedded from skills/, where each AI agent (harness) keeps them, and installing one skill with github.com/strongo/cli-helpers/skillsync.

Each skill is its own skillsync bundle, PluginIdentity{openvaultdb, <skill>}, under the shared CLI Identity{openvaultdb, ovdb}, so installing one never changes the other or skills other tools own (REQ:install-with-skillsync). Harness names, directories and discovery are cobracmd.DefaultHarnesses.

Nothing here decides consent: callers write only after a person chose a skill and its targets (REQ:explicit-consent-to-install). Directories are resolved by whoever runs the interface — the CLI and TUI from their own environment, the server for the web console — and a server checks what a client sent with CheckTarget (REQ:install-targets-restricted).

Index

Constants

View Source
const (
	Storage = "openvaultdb"
	Todo    = "todo-demo"
)

Skill ids, as `ovdb skills install <id>` names them.

View Source
const (
	// ActionInstall opens the consent step for the skill whose id ends the
	// entry's command.
	ActionInstall = "install_skill"
	// ActionSkills opens AI agent skills.
	ActionSkills = "skills"
)

Next actions presentations act on in place (envelope.Next.Action).

View Source
const (
	StateNotInstalled    = "not_installed"
	StateInstalled       = "installed"
	StateUpdateAvailable = "update_available"
	// StateChanged is an OVDB-installed copy the person edited since.
	StateChanged = "changed"
	// StateNotOVDB is a folder of the same name OVDB didn't install and
	// can't take over: it isn't this skill, or holds files the skill doesn't.
	StateNotOVDB = "not_ovdb"
	// StateAdoptable is a folder of the same name OVDB didn't install that is
	// this skill already (its SKILL.md names it, and it holds nothing the
	// skill doesn't): installing takes it over, keeping a backup of it.
	StateAdoptable = "adoptable"
	// StateRecoveryPending is a skills folder where an earlier install was
	// interrupted and left its recovery journal: skillsync cannot plan
	// anything there until a real install has finished or undone it, so what
	// would happen to this skill is not known (and it is not "not installed",
	// "another skill" or "not adoptable"). Installing finishes the recovery
	// first, and takes over nothing the person did not agree to.
	StateRecoveryPending = "recovery_pending"
	// StateRecordUnusable is a skills folder whose record of what OVDB (or
	// another tool) installed cannot be used: the file does not parse, or a newer
	// tool wrote a schema this build does not know. Nothing about this skill can
	// be said, and it is not "another skill with this name".
	StateRecordUnusable = "record_unusable"
)

Target states: how an installed skill compares with this build's.

View Source
const AdoptableParam = "adoptable"

AdoptableParam is the query parameter of GET /api/local/v1/skills with which a client says it understands the state "adoptable". Without it the server reports such a target as not_ovdb, the state every version before adoption knows for a folder OVDB did not install: a client built before adoption existed has no text for the new state.

View Source
const Publisher = "openvaultdb"

Publisher is the skillsync publisher of the CLI and of every bundle.

View Source
const RecoveryParam = "recovery"

RecoveryParam is the query parameter of GET /api/local/v1/skills with which a client says it understands the state "recovery_pending" and the target field "state_reason". Without it the client is told what every version before this told it for such a folder: not_ovdb (see Document.WithoutRecoveryPending). The listing is never replaced by an error because one folder has an interrupted install.

Variables

View Source
var CLI = skillsync.Identity{Publisher: Publisher, Name: "ovdb"}

CLI is the skillsync identity of ovdb, recorded as each bundle's supplier.

View Source
var Definitions = []Definition{
	{ID: Storage, Dir: "openvaultdb", /* contains filtered or unexported fields */},
	{ID: Todo, Dir: "openvaultdb-todo-demo", /* contains filtered or unexported fields */},
}

Definitions are the skills, in the order interfaces list them.

States are the Target states, in the order this package defines them. Every one has a "skills.state.<state>" entry in copy/en.json (TestEveryStateAndResultHasText).

Functions

func AdoptedBackupText added in v0.22.0

func AdoptedBackupText(dryRun bool, outcome Outcome) string

AdoptedBackupText says where the copy that was already there is kept, or in a dry run that one would be.

func Canonical

func Canonical(path string) string

Canonical is path with the symbolic links of its deepest existing ancestor resolved, so a home reached through a link is used by its real path (skillsync refuses symlinked ancestors).

func CheckTarget

func CheckTarget(d Definition, home string, t RequestTarget) error

CheckTarget is the server's check of a target a client resolved (REQ:install-targets-restricted): a harness target must match that harness's layout (<root>/<config folder>/skills, or <root>/skills for a harness whose config root a variable can move); a target without a harness, the CLI's --dir, must be under home.

func CheckUnderHome

func CheckUnderHome(d Definition, home, dir string) error

CheckUnderHome refuses a --dir that is not a directory inside home, so an install never writes to system or other people's folders.

func ConsentText added in v0.22.0

func ConsentText(state string) string

ConsentText is the note the consent step shows under an agent whose copy of the skill is in this state, or "" when the state needs none (or is not one).

func Harness

func Harness(id string) (cobracmd.Harness, bool)

Harness is the cobracmd harness named by id or one of its aliases.

func HarnessName

func HarnessName(id string) string

HarnessName is harness id's people-facing name.

func InstallNext

func InstallNext(id string) envelope.Next

InstallNext is the next entry that offers installing skill id, for the Results of other actions (todo-demo#REQ:demo-next-actions).

func ResultLine added in v0.22.0

func ResultLine(outcome Outcome) string

ResultLine is one target of an install as the TUI and web console list it: the agent's name and folder, and for an adopted folder where the copy that was there is kept.

func ResultText added in v0.22.0

func ResultText(result string) string

ResultText is what an install result reads as in a line: the copy for "skills.result.<result>". A result is a skillsync action, which this build may not know (a newer library, or a newer server answering an older client); that one is shown as it came, not as a panic of uicopy.T.

func ResultTextFor added in v0.22.0

func ResultTextFor(result string, dryRun bool) string

ResultTextFor is ResultText, worded as a plan for a dry run: an adopted folder has not been taken over yet.

func StateText added in v0.22.0

func StateText(state string) string

StateText is what a target state reads as: "skills.state.<state>", or the state as it came when this build has no text for it.

func TelemetryEvents added in v0.18.0

func TelemetryEvents(request InstallRequest, body []byte, err error) []telemetry.Event

TelemetryEvents are the skill_installed events for one install request and its result (telemetry-consent#REQ:closed-event-set): one per target, with the harness id only, never a directory. A dry run reports nothing; a failure reports each requested harness as unsuccessful plus onboarding_error.

func UnknownSkill

func UnknownSkill(id string) *envelope.Error

UnknownSkill is the invalid_argument for a skill id that doesn't exist.

Types

type Build

type Build struct {
	Version  string
	Revision string
}

Build is the ovdb build installing: its version and VCS revision.

func (Build) Install

func (b Build) Install(ctx context.Context, e Env, d Definition, targets []RequestTarget, dryRun, replaceChanged bool, consent Consent) (InstallDocument, error)

Install installs skill d into each target with one skillsync.Sync per target and only d's bundle (capability 21). Targets must already be checked. Every target is attempted; a failure in any makes the whole install fail, naming each outcome.

type Consent struct {
	// All is a person's yes for every target (the request field "adopt").
	All       bool
	Dirs      []string
	Harnesses []string
}

Consent says which target folders an install may take over. The zero value is none, the answer every client that does not know adoption expects.

type Definition

type Definition struct {
	ID string
	// Dir is the skill's directory, in skills/ and in a harness's skills
	// directory.
	Dir string
	// contains filtered or unexported fields
}

Definition is one embedded skill.

func Find

func Find(id string) (Definition, bool)

Find is the definition for id.

func (Definition) Plugin

func (d Definition) Plugin() skillsync.PluginIdentity

Plugin is the skill's own skillsync identity.

type Document

type Document struct {
	Schema int             `json:"schema"`
	Skills []Skill         `json:"skills"`
	Next   []envelope.Next `json:"next"`
}

Document is the body of GET /api/local/v1/skills and `ovdb skills list --json`.

func Inspect

func Inspect(e Env) Document

Inspect is the skills document for e (capability 20). It only reads.

func (Document) WithoutAdoptable added in v0.22.0

func (d Document) WithoutAdoptable() Document

WithoutAdoptable is d as a client that does not know the state "adoptable" is told it: an adoptable target is another's folder.

func (Document) WithoutRecoveryPending added in v0.29.0

func (d Document) WithoutRecoveryPending() Document

WithoutRecoveryPending is d as a client that does not know the states "recovery_pending" and "record_unusable" is told them: a folder with an interrupted install, or whose record cannot be used, is another's folder, as it was before those states existed.

func (Document) WithoutStateReasons added in v0.29.0

func (d Document) WithoutStateReasons() Document

WithoutStateReasons is d without the target field "state_reason", as a client that predates it is sent the document.

type Env

type Env struct {
	Home   string
	Getenv func(string) string
}

Env is where one interface resolves harness directories: the person's home and environment variables of the process that runs the interface (local-server-and-web-console#REQ:client-values-and-mismatch).

func EnvFrom

func EnvFrom(getenv func(string) string) (Env, error)

EnvFrom resolves the home from getenv (HOME, or USERPROFILE on Windows), falling back to os.UserHomeDir.

func (Env) Describe

func (e Env) Describe(d Definition) Skill

Describe is skill d with its targets.

func (Env) Plan

func (e Env) Plan(d Definition, targets []RequestTarget) []Target

Plan describes targets for d without writing: what an interface shows before the person decides.

func (Env) Resolve

func (e Env) Resolve(request InstallRequest) (Definition, []RequestTarget, error)

Resolve checks request's skill and turns what it names into targets: Targets as sent, Harnesses resolved in e. Without either it is every harness found, or Claude Code when none is (cobracmd's discovery).

func (Env) Targets

func (e Env) Targets(d Definition) []Target

Targets are the harnesses shown for d: every one found, plus Claude Code and Codex, in cobracmd.DefaultHarnesses order.

type InstallDocument

type InstallDocument struct {
	Schema int    `json:"schema"`
	Skill  string `json:"skill"`
	Dir    string `json:"dir"`
	Name   string `json:"name"`
	DryRun bool   `json:"dry_run,omitempty"`
	// AlreadyUpToDate is set when no target changed.
	AlreadyUpToDate bool            `json:"already_up_to_date"`
	Outcomes        []Outcome       `json:"targets"`
	Next            []envelope.Next `json:"next"`
}

InstallDocument is the body of POST /api/local/v1/skills/install and the --json output of `ovdb skills install`.

type InstallRequest

type InstallRequest struct {
	Skill     string          `json:"skill"`
	Harnesses []string        `json:"harnesses,omitempty"`
	Targets   []RequestTarget `json:"targets,omitempty"`
	DryRun    bool            `json:"dry_run,omitempty"`
	// ReplaceChanged replaces a copy the person edited since OVDB installed
	// it; only after they agreed to lose those edits.
	ReplaceChanged bool `json:"replace_changed,omitempty"`
	// Adopt takes over, in every target, a folder that was already there and
	// already is this skill, keeping a backup of it; only after the person
	// agreed to that. It is what clients from v0.22.0 to v0.28.x send. Without
	// it (and without AdoptDirs and AdoptHarnesses) such a folder is refused
	// and left untouched, which is what every client built before adoption
	// existed (v0.21.0) expects: the server never sends one a state or result
	// it did not ask for.
	Adopt bool `json:"adopt,omitempty"`
	// AdoptDirs are the skill folders (Target.Dir) the person was shown as
	// already there and agreed to have taken over. A folder that became
	// adoptable after they were shown the list is not among them, so it is
	// refused. The CLI and TUI send it instead of Adopt.
	AdoptDirs []string `json:"adopt_dirs,omitempty"`
	// AdoptHarnesses is AdoptDirs for the web console, which names harnesses
	// and never a directory.
	AdoptHarnesses []string `json:"adopt_harnesses,omitempty"`
}

InstallRequest is the body of POST /api/local/v1/skills/install. The web console sends Harnesses, which the server resolves itself; the CLI and TUI send Targets they resolved. A console session may not name a directory.

func (InstallRequest) Consent added in v0.29.0

func (r InstallRequest) Consent() Consent

Consent is the folders a person agreed to have taken over, as a request says it.

type Installed

type Installed struct {
	ID           string   `json:"id"`
	InstalledFor []string `json:"installed_for"`
	// UpdateAvailableFor lists the harnesses whose copy an older ovdb
	// installed; `ovdb skills install <id>` updates it.
	UpdateAvailableFor []string `json:"update_available_for"`
	// ChangedFor lists the harnesses whose copy the person edited.
	ChangedFor []string `json:"changed_for"`
}

Installed is the status document's skills field group: each skill with the harnesses it is installed for (first-run-onboarding#REQ:status-command).

func Status

func Status(e Env) []Installed

Status lists every skill and where it is installed, reading only skillsync's markers.

type Outcome

type Outcome struct {
	Target
	// Result is one of skillsync's actions: added, updated, unchanged,
	// adopted, conflict (removed is never planned for an install).
	Result string `json:"result"`
	Reason string `json:"reason,omitempty"`
	// BackupPath is where the copy that was already there is kept after
	// Result adopted; empty for every other result and for a dry run.
	BackupPath string `json:"backup_path,omitempty"`
}

Outcome is what installing did in one target.

type RequestTarget

type RequestTarget struct {
	Harness   string `json:"harness,omitempty"`
	SkillsDir string `json:"skills_dir"`
}

RequestTarget is one target an install request names: a harness id with the skills directory the client resolved, or, from the CLI's --dir, a directory alone.

type Skill

type Skill struct {
	ID      string `json:"id"`
	Dir     string `json:"dir"`
	Name    string `json:"name"`
	Purpose string `json:"purpose"`
	Example string `json:"example"`
	// Command installs it; interfaces show it next to Install.
	Command string   `json:"command"`
	Targets []Target `json:"targets"`
	// InstalledFor lists the harnesses it is installed for.
	InstalledFor []string `json:"installed_for"`
}

Skill is one skill in the skills document.

type Target

type Target struct {
	Harness string `json:"harness,omitempty"`
	Name    string `json:"name"`
	// SkillsDir is the harness's skills directory.
	SkillsDir string `json:"skills_dir"`
	// Dir is where this skill is, or would be, installed.
	Dir       string `json:"dir"`
	Detected  bool   `json:"detected"`
	Installed bool   `json:"installed"`
	// State is one of the State constants.
	State string `json:"state"`
	// StateReason is skillsync's own reason for the state where it says more
	// than the state does: for another's folder what was found in it (a stray
	// ".DS_Store" in a copy of this skill), for a pending recovery what is
	// wrong. Empty for every other state, and left out of documents for
	// clients that predate it (see Document.ForClient).
	StateReason string `json:"state_reason,omitempty"`
}

Target is one place a skill can be installed: a harness's skills directory, or, for the CLI's --dir, any directory under the home.

Directories

Path Synopsis
Package skillstest is the test support of the packages that show or install AI agent skills: what an interrupted install leaves behind.
Package skillstest is the test support of the packages that show or install AI agent skills: what an interrupted install leaves behind.

Jump to

Keyboard shortcuts

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