skillinject

package
v1.9.3 Latest Latest
Warning

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

Go to latest
Published: May 7, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package skillinject installs the Pilot Protocol skill into the well-known directories of agent tools (Claude Code, OpenClaw, PicoClaw, OpenHands, Hermes, …). The configuration — what to inject, where, and what marker content to upsert into each tool's heartbeat file — is fetched at runtime from the pilot-skills repository on GitHub. There is no embedded fallback: a tick that cannot reach the network is logged and skipped; the next tick retries.

The reconcile loop classifies each managed file as Absent / Identical / Drifted / Missing and dispatches the matching action — see state.go.

Index

Constants

View Source
const DefaultInterval = 15 * time.Minute

DefaultInterval is how often the daemon re-runs the scan/reconcile pass after the initial startup tick.

View Source
const DefaultManifestURL = "https://raw.githubusercontent.com/TeoSlayer/pilot-skills/main/inject-manifest.json"

DefaultManifestURL is the canonical raw GitHub URL for the inject manifest. Overridable via Config.ManifestURL (test hook).

View Source
const DefaultRepoBaseURL = "https://raw.githubusercontent.com/TeoSlayer/pilot-skills/main/"

DefaultRepoBaseURL is the prefix used to fetch any path the manifest references (skills/<name>/SKILL.md, heartbeats/<tool>.md). Overridable via Config.RepoBaseURL.

Variables

This section is empty.

Functions

func IsEnabled

func IsEnabled(home string) bool

IsEnabled returns whether skill injection is on. Defaults to TRUE (opt-out, not opt-in) when the flag isn't present, so fresh installs get the feature without any extra step.

func Run

func Run(ctx context.Context, cfg Config)

Run blocks running scan/reconcile ticks until ctx is cancelled. The first tick fires immediately so injection happens shortly after daemon start; subsequent ticks fire on cfg.Interval.

func SetEnabled

func SetEnabled(home string, enabled bool) error

SetEnabled persists the opt-out flag. Reads the existing config (if any), updates only the skill_inject key, writes back atomically.

Types

type Action

type Action string

Action is what the reconcile loop chose to do in response to a State.

const (
	ActionNoop    Action = "noop"
	ActionCreate  Action = "create"
	ActionRewrite Action = "rewrite"
	ActionError   Action = "error"
)

type Config

type Config struct {
	// Home overrides the user home dir (test hook).
	Home string
	// Interval between scan ticks after the initial startup tick.
	Interval time.Duration
	// ManifestURL overrides the canonical raw GitHub URL for inject-manifest.json.
	ManifestURL string
	// RepoBaseURL overrides the prefix used to resolve relative paths in
	// the manifest (skills/<name>/SKILL.md, heartbeats/<tool>.md).
	RepoBaseURL string
	// HTTPClient overrides the HTTP client used for fetching.
	HTTPClient *http.Client
}

Config tunes the injector. Zero values use sensible defaults.

type EnabledFlag

type EnabledFlag struct {
	Enabled bool `json:"enabled"`
}

EnabledFlag describes the persisted opt-out state. Stored at ~/.pilot/config.json under "skill_inject" → {"enabled": bool}.

type FileKind

type FileKind string

FileKind names which of a target's two files an Outcome is about.

const (
	KindSkill  FileKind = "skill"
	KindMarker FileKind = "marker"
	KindHelper FileKind = "helper"
)

type Manifest

type Manifest struct {
	Version     int              `json:"version"`
	Entrypoint  string           `json:"entrypoint"`
	Description string           `json:"description,omitempty"`
	Tools       []ManifestTool   `json:"tools"`
	Helpers     []ManifestHelper `json:"helpers,omitempty"`
}

Manifest mirrors inject-manifest.json. Field tags match the upstream schema. Unknown fields are ignored (forward-compat with new tool fields).

type ManifestHelper

type ManifestHelper struct {
	Name string `json:"name"`
	// Src is a repo-relative path fetched via fetchRepoFile, e.g.
	// "workflow-injection/pilot-ask".
	Src string `json:"src"`
	// Dst is the absolute install target. Supports ~/ expansion, e.g.
	// "~/.pilot/bin/pilot-ask".
	Dst string `json:"dst"`
	// Mode is the file mode in octal string form, e.g. "0755". Empty
	// defaults to 0755 (helpers are executables).
	Mode string `json:"mode,omitempty"`
}

ManifestHelper is one helper script the daemon installs at a well-known path so any AI tool on the host can invoke it. Used to ship pilot-ask (the directory + specialist round-trip wrapper).

Helpers are tool-agnostic — they live under ~/.pilot/bin/ and are referenced by every tool's heartbeat directive.

type ManifestTool

type ManifestTool struct {
	Name              string `json:"name"`
	RootDir           string `json:"rootDir"`
	SkillsDir         string `json:"skillsDir"`
	HeartbeatPath     string `json:"heartbeatPath,omitempty"`
	HeartbeatTemplate string `json:"heartbeatTemplate,omitempty"`
	SkillNaming       string `json:"skillNaming,omitempty"` // "" = "directory" (default), "flat" = single-file
	SelfHeartbeat     bool   `json:"selfHeartbeat,omitempty"`
}

ManifestTool is one tool target row.

type Outcome

type Outcome struct {
	Tool   string   `json:"tool"`
	Kind   FileKind `json:"kind"`
	Path   string   `json:"path"`
	State  State    `json:"state"`
	Action Action   `json:"action"`
	Hash   string   `json:"hash,omitempty"`
	Err    string   `json:"err,omitempty"`
}

Outcome records one reconcile decision.

type Report

type Report struct {
	At       time.Time `json:"at"`
	Outcomes []Outcome `json:"outcomes"`
	Skipped  []string  `json:"skipped,omitempty"`
	// Disabled is true if the tick was a no-op because the user has
	// `pilotctl skills disable`'d injection.
	Disabled bool `json:"disabled,omitempty"`
}

Report is the result of one Tick.

func Tick

func Tick(ctx context.Context, cfg Config) (*Report, error)

Tick performs one scan + reconcile pass and returns a Report. Network failures abort the tick and return an error — there is no embedded fallback. Exposed for tests, one-shot use, and `pilotctl skills check`.

If the user has disabled skill injection via `pilotctl skills disable` (persisted in ~/.pilot/config.json), Tick returns an empty report without touching disk or the network.

func (*Report) Counts

func (r *Report) Counts() map[Action]int

Counts returns how many outcomes hit each Action.

type State

type State string

State is the classification of one managed file at the start of a tick.

const (
	// File (or marker block) does not exist on disk.
	StateAbsent State = "absent"
	// File/marker exists and matches the canonical we want.
	StateIdentical State = "identical"
	// File/marker exists but the content/hash differs from canonical.
	StateDrifted State = "drifted"
)

Jump to

Keyboard shortcuts

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