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
- Variables
- func AdoptedBackupText(dryRun bool, outcome Outcome) string
- func Canonical(path string) string
- func CheckTarget(d Definition, home string, t RequestTarget) error
- func CheckUnderHome(d Definition, home, dir string) error
- func ConsentText(state string) string
- func Harness(id string) (cobracmd.Harness, bool)
- func HarnessName(id string) string
- func InstallNext(id string) envelope.Next
- func ResultLine(outcome Outcome) string
- func ResultText(result string) string
- func ResultTextFor(result string, dryRun bool) string
- func StateText(state string) string
- func TelemetryEvents(request InstallRequest, body []byte, err error) []telemetry.Event
- func UnknownSkill(id string) *envelope.Error
- type Build
- type Consent
- type Definition
- type Document
- type Env
- type InstallDocument
- type InstallRequest
- type Installed
- type Outcome
- type RequestTarget
- type Skill
- type Target
Constants ¶
const ( Storage = "openvaultdb" Todo = "todo-demo" )
Skill ids, as `ovdb skills install <id>` names them.
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).
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.
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.
const Publisher = "openvaultdb"
Publisher is the skillsync publisher of the CLI and of every bundle.
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 ¶
var CLI = skillsync.Identity{Publisher: Publisher, Name: "ovdb"}
CLI is the skillsync identity of ovdb, recorded as each bundle's supplier.
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.
var States = []string{StateNotInstalled, StateInstalled, StateUpdateAvailable, StateChanged, StateNotOVDB, StateAdoptable, StateRecoveryPending, StateRecordUnusable}
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
AdoptedBackupText says where the copy that was already there is kept, or in a dry run that one would be.
func Canonical ¶
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
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 HarnessName ¶
HarnessName is harness id's people-facing name.
func InstallNext ¶
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
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
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
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
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 ¶
UnknownSkill is the invalid_argument for a skill id that doesn't exist.
Types ¶
type Build ¶
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 ¶ added in v0.29.0
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 (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 (Document) WithoutAdoptable ¶ added in v0.22.0
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
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
WithoutStateReasons is d without the target field "state_reason", as a client that predates it is sent the document.
type Env ¶
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 ¶
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).
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. |