Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type CopyState ¶ added in v0.7.21
CopyState records what one on-disk copy of a skill looked like at the last time the mirror reconciled it. A skill lives in N agent directories, each independently editable; a single ContentHash can't say which copy moved. The per-copy baseline can. SyncedAt is a display hint only — it must never be the thing that decides which edit wins (that path silently discards an edit; see cli-per-copy-skill-divergence.md).
type ShadowInfo ¶ added in v0.7.3
type ShadowInfo struct {
SkillID string
Slug string
OrgSlug string // winning org slug; empty for cross-org shadow on the loser side
}
ShadowInfo records a server-reported shadow on one of the caller's skills (migration 047). Returned by fetchShadowMap so pull can skip shadowed slugs and emit a warning instead of writing them to disk.
type SkillConflictError ¶ added in v0.7.3
type SkillConflictError struct {
Slug string // the slug that conflicted (the one the user tried to create)
Source string // "user" or "org" — where the conflicting skill lives
OwnerOrOrgSlug string // org slug when Source=="org"; empty otherwise
ServerMessage string // verbatim server `message` if present
}
SkillConflictError is returned by createSkill when the server's effective-skills check (migration 047) rejects a new slug because it already exists in the caller's user-or-org-inherited skill set. Push surfaces this with a hint pointing at `airskills mv`.
func (*SkillConflictError) Error ¶ added in v0.7.3
func (e *SkillConflictError) Error() string
type SkillState ¶ added in v0.5.27
type SkillState string
SkillState is the presence/lifecycle state of a single skill on this machine — the FIRST axis of the unified divergence model (platform/doc/changes/unify-skill-divergence-state-model.md). It is determined first and is mutually exclusive, from the (Local, Marker, Remote) presence triple alone.
The SECOND axis — HOW a tracked skill diverges — is carried by the three orthogonal booleans on SkillStateInfo (LocalDirty, RemoteMoved, UpstreamMoved), never by this enum. The old flat vocabulary (synced/modified/modified-pending) collapsed those two axes into one 1-D encoding and could not name the (clean, upstream-moved) cell, which is why `list` and `status` disagreed. `decideState` is the single divergence classifier; every command projects from its output.
User-facing description: doc/internals/sync-state.mdx in the platform repo.
const ( // StateAvailable — server has a skill the user has not installed on // this machine. Rendered as "—" in `airskills list`. (was not-local) StateAvailable SkillState = "available" // StateUntracked — local dir exists, no marker, and the server has no // skill that could account for it. Common when a skill arrived via git // rather than `airskills add`. StateUntracked SkillState = "untracked" // StateAdoptable — local dir exists, no marker, but the server has a // skill of the same name whose bytes match exactly. Next sync silently // claims it. (was linked) StateAdoptable SkillState = "adoptable" // StateConflict — local dir exists, no marker, server has a same-named // skill whose bytes differ. Folds the old untracked-conflict AND the // parked pending-conflict copy into one state, one report. (was // untracked-conflict) StateConflict SkillState = "conflict" // StateTracked — local dir, marker, and remote all present. How it // diverges is read off the (LocalDirty, RemoteMoved, UpstreamMoved) // booleans, not off this value. (replaces synced / modified / // modified-pending) StateTracked SkillState = "tracked" // StateOrphaned — local dir + marker, but the server no longer has the // skill (404 / archived). (was markerStateOrphan / orphan-*) StateOrphaned SkillState = "orphaned" // StateDisplaced — local dir + marker, but the name now belongs to a // different skill on the server (transferred away or org-shadowed). // (folds markerStateMoved / moved-keep / shadowed) StateDisplaced SkillState = "displaced" )
type SkillStateInfo ¶ added in v0.5.27
type SkillStateInfo struct {
// Name is the local directory name when the skill exists locally,
// otherwise the server slug. Stable across server-side renames because
// tracking matches by skill_id first.
Name string
State SkillState
// Local is true when the skill has a directory on this machine.
Local bool
// Remote is the server-side view, if the server knows about this skill.
// Nil for purely-local untracked directories.
Remote *apiSkill
// Marker is the sync.json entry for this skill, if one exists.
Marker *SyncEntry
// LocalHash is the Merkle hash of on-disk content. Empty when the skill
// is not present locally.
LocalHash string
// The four divergence coordinates of the unified model. Meaningful only
// when State == StateTracked; all false otherwise. Sourced is the
// ownership axis; the other three are the orthogonal divergence flags.
Sourced bool // a Source/forked_from upstream pointer exists
LocalDirty bool // working ≠ base — I have edits not yet pushed
RemoteMoved bool // my_remote_head ≠ base — another of my machines pushed
UpstreamMoved bool // forks only: the parent moved past upstream_base
// Overlay marks the one-skill shape for non-owned skills: the marker
// tracks the UPSTREAM id, local edits are an overlay backed up in a
// hidden fork (cli-one-skill-overlay-and-lineage-split.md). For overlay
// rows the matched remote IS the upstream, so RemoteMoved stays false;
// standing divergence from the upstream is OverlayDiverged ("local
// changes"), and UpstreamMoved means the upstream moved past the
// baseline the user last incorporated.
Overlay bool
OverlayDiverged bool // local ≠ upstream head — the user's standing edits
}
SkillStateInfo is one row of classifier output. The classifier emits one row per server-known skill plus one row per local directory that has no marker and no matching server skill.
type SkillsetNotFoundError ¶ added in v0.5.24
SkillsetNotFoundError is returned when the server reports an unknown skillset slug on /api/v1/skills. Callers render it as a human-readable hint listing the user's available skillsets.
func (*SkillsetNotFoundError) Error ¶ added in v0.5.24
func (e *SkillsetNotFoundError) Error() string
type SyncEntry ¶ added in v0.3.0
type SyncEntry struct {
SkillID string `json:"skill_id"`
Version string `json:"version"`
ContentHash string `json:"content_hash,omitempty"`
Tool string `json:"tool"`
// Copies is the per-copy reconciliation ledger, keyed by absolute
// skill-dir path. Seeded at marker creation (seedCopyLedgerFromDisk)
// and maintained by the mirror (mirrorLocalSkills); used to tell which
// agent copy of a skill diverged. Empty only for legacy markers, in
// which case a divergence is surfaced for reconciliation rather than
// guessed (never mtime, never the marker-wide hash). See
// cli-per-copy-skill-divergence.md.
Copies map[string]CopyState `json:"copies,omitempty"`
OwnerKind string `json:"owner_kind,omitempty"` // "user" or "org"
OwnerSlug string `json:"owner_slug,omitempty"` // e.g. "chrismdp" or "cherrypick"
// LocalAlias is the on-disk directory name when it differs from
// the server slug. Set by `airskills add --as <alias>` and by the
// on-disk migration when it has to disambiguate a rename
// collision. Empty means "dir name matches server slug." The
// marker stays the source of truth — see CLAUDE.md "Org
// namespacing lives in the marker, not on disk."
LocalAlias string `json:"local_alias,omitempty"`
Source *skillSource `json:"source,omitempty"`
// Backup references the hidden backup fork holding this skill's local
// edits when the caller can't write the upstream. Only meaningful on
// overlay markers (SkillID == the upstream's id). Cleared when the
// edits land upstream (admin fold-in / accepted suggestion) or the
// backup is promoted to a visible personal skill (upstream lost).
Backup *backupRef `json:"backup,omitempty"`
// ResolvedHash records the upstream content hash the user last
// reviewed against via `airskills resolve`. Only meaningful for
// sourced skills (Source != nil). Empty for owned skills, and for
// sourced skills the user has never resolved against — in that
// case the classifier treats any divergence as modified-pending.
ResolvedHash string `json:"resolved_hash,omitempty"`
SuggestionID string `json:"suggestion_id,omitempty"`
SuggestDeclined bool `json:"suggest_declined,omitempty"`
// Deleted is set when the skill was transferred away and local edits
// prevent removing the old dir. Pushes are blocked for deleted markers.
Deleted bool `json:"deleted,omitempty"`
MovedTo string `json:"moved_to,omitempty"` // new dir name after transfer
}
SyncEntry tracks the sync state of a single skill.
OwnerKind / OwnerSlug record the skill's CURRENT namespace as last seen on the server. They get updated after every push so a server-side transfer is picked up on the next push without a separate sync step. If they change between pushes, the local dir is renamed to match.
type SyncState ¶ added in v0.3.0
type SyncState struct {
Version int `json:"version"`
Skills map[string]*SyncEntry `json:"skills"`
// LastSuggestionNotifyAt is the cutoff for printing suggestion
// accept/decline notifications. Anything reviewed at or before this
// has already been shown. Stateless alternative to tracking IDs.
LastSuggestionNotifyAt string `json:"last_suggestion_notify_at,omitempty"`
}
SyncState holds sync metadata for all tracked skills. Stored at ~/.config/airskills/sync.json, keyed by local directory name.
Source Files
¶
- add.go
- add_collision.go
- agent_messages.go
- agents.go
- api.go
- autoupdate.go
- bundle.go
- color.go
- commit_resolve.go
- configure.go
- copy_baselines.go
- diff.go
- doctor.go
- export.go
- feedback.go
- file_mode.go
- github.go
- hash.go
- history.go
- ignore.go
- intra_skill_deletions.go
- list.go
- log.go
- login.go
- marker_resolve.go
- mv.go
- next_steps.go
- once.go
- org.go
- org_skillset.go
- overlay.go
- owner_resolver.go
- pending_conflicts.go
- pending_review.go
- progress.go
- publish.go
- pull.go
- pull_keeplocal.go
- push.go
- reexec_unix.go
- resolve.go
- restore.go
- review.go
- rm.go
- root.go
- selfupdate.go
- share.go
- skill_state.go
- skill_validation.go
- skillset.go
- skipped_marker.go
- status.go
- subscription_lifecycle.go
- sync.go
- sync_helpers.go
- syncstate.go
- transfer.go
- transfer_notice.go
- update.go
- updatecheck.go